Jump to content

Create a MsgBox with buttons disabled for specific amount of time


Go to solution Solved by argumentum,

Recommended Posts

Hi,

I would like to create an message box with disabled buttons for specified amount of time

after that period the buttons should be automatically enabled.

 

Example code (but not working as desired):

MsgBox(64, 'Sometitle', 'Please make sure to read this' & @CRLF & 'Are you sure want to continue ?')
Sleep(5000)

 

I'm wondering If such a thing could be achieved

Waiting for your thoughts, thank you!

Link to comment
Share on other sites

  • Moderators

You could make customized MsgBox() funcs (I believe that's the route Melba took, haven't looked in years) like @argumentum suggested.

You could write an outside script and execute before the msgbox to disable the message box button (eg using run() to run script from memory or from an executable) before the msgbox (way more of a hassle me thinks).

You could set windows hooks, I did it here: 

But I didn't add a disable/timer option, but it's totally possible. (Warning, I haven't updated that thing in years but the concept is still there)

Honestly, with the way Melba keeps up with things, if he has that option, that's probably the way to go.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

@argumentum Nice, this UDF seems to be really great it's has more features and options more than the usual MsgBox

 

Now I'm trying to figure out how could I add some buttons into this example.

Here's the same example used in _ExtMsgBox:

#include "ExtMsgBox.au3"

; Set the message box right justification, not TOPMOST, disable closure, colours (orange text on green background) and change font
_ExtMsgBoxSet(1 + 2 + 64, 0)

$sMsg = "Please make sure to read this:" & @CRLF
$sMsg &= "Some important text is here" & @CRLF & @CRLF
$sMsg &= "Are you sure want to continue ?"

_ExtMsgBox(128, " ", "Test 6", $sMsg, 20, 100, 500)

; Reset to default
_ExtMsgBoxSet(Default)

After the message box timeout is finished the button should be enabled

only then the user can click on the button, If user didn't click on the button then the message box should be remained.

Edited by simplercoder000
Some typo fixes
Link to comment
Share on other sites

57 minutes ago, SmOke_N said:

You could write an outside script and execute before the msgbox to disable the message box button

If StringInStr($CmdLineRaw, "/MyMessingAroundWithyMsgBox") Then Exit MyMessingAroundWithyMsgBox()
Func MyMessingAroundWithyMsgBox()
    AutoItWinSetTitle("MyMessingAroundWithyMsgBox")
    Local $sTitle = StringTrimRight(@ScriptName, 4), $sText = "Please make sure to", $sCtrl = "Button1"
    WinWait($sTitle, $sText)
    ControlDisable($sTitle, $sText, $sCtrl)
    For $n = 5 To 1 Step -1
        ControlSetText($sTitle, $sText, $sCtrl, $n)
        Sleep(999)
    Next
    ControlSetText($sTitle, $sText, $sCtrl, "&Ok")
    ControlEnable($sTitle, $sText, $sCtrl)
EndFunc

TellThemAndTellThemGood()
Func TellThemAndTellThemGood()
    ShellExecute(@AutoItExe, '"' & @ScriptFullPath & '" /MyMessingAroundWithyMsgBox')
    WinWait("MyMessingAroundWithyMsgBox")
    Local $sMsg = "Please make sure to read this:" & @CR
    $sMsg &= "Some important text is here" & @CR & @CR
    $sMsg &= "Are you sure want to continue ?"
    MsgBox(262144 + 64, StringTrimRight(@ScriptName, 4), $sMsg, 60)
EndFunc

This is what you would like to see @simplercoder000, right ?

Edited by argumentum
better code

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

7 minutes ago, argumentum said:

This is what you would like to see @simplercoder000, right ?

Yes, that's what I wanted to see exactly even the timeout are in the button itself.

But I think there's an glitch in the MessageBox, the timeout can be skipped by fast clicking on the button.

Also is it possible to write this in more easier way ?

 

Link to comment
Share on other sites

  • Moderators

Hide it if you're having issues (ControlHide/ControlShow if you're using @argumentum's example)

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

13 minutes ago, simplercoder000 said:

But I think there's an glitch in the MessageBox, the timeout can be skipped by fast clicking on the button.

No it can not while the button is disable. But it does take time until it get's disable, some, 300 or less mSec ?.

The notion is there. If anyone click that fast on it is because they are aware and tired of it.
What are you going to use this in that it has to be a MsgBox() ?. Couldn't you code your own GUI ?

Edit: I made changes to make it faster at disabling it.

Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

17 minutes ago, simplercoder000 said:

Also is it possible to write this in more easier way ?

.. :lol:, ...just reading. Look. Coding is tedious, slow, error until there are none. If you wanna code, you're gonna have to learn to pace yourself.

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

Another way :

#include <WinAPI.au3>

Global $bEnable, $hHook

Example()

Func Example()
  Local $hProc = DllCallbackRegister(CbtHookProc, "int", "int;int;int")
  $hHook = _WinAPI_SetWindowsHookEx($WH_CBT, DllCallbackGetPtr($hProc), 0, _WinAPI_GetCurrentThreadId())
  $bEnable = False
  MsgBox(0, "test", "test",5)
  $bEnable = True
  Local $iRet = MsgBox(0, "test", "test")
  _WinAPI_UnhookWindowsHookEx($hHook)
  DllCallbackFree($hProc)
EndFunc   ;==>Example2

Func CbtHookProc($nCode, $wParam, $lParam)
  If $nCode = 5 Then ; 5=HCBT_ACTIVATE
    $hWnd = HWnd($wParam)
    If Not $bEnable Then ControlDisable($hWnd, "", "Button1")
  EndIf
  Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc   ;==>CbtHookProc

 

Link to comment
Share on other sites

41 minutes ago, SmOke_N said:

Hide it if you're having issues (ControlHide/ControlShow if you're using @argumentum's example)

I tried this but it's not what I needed.

 

35 minutes ago, argumentum said:

No it can not while the button is disable. But it does take time until it get's disable, some, 300 or less mSec ?.

I don't want them to skip it, because this is gone be displayed every time they run the program.

35 minutes ago, argumentum said:

What are you going to use this in that it has to be a MsgBox() ?. Couldn't you code your own GUI ?

Here's an example on what I want to achieve:

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>

$MsgText = 'Continue using this software at your own risk !' & @CRLF
$MsgText &= 'By clicking on OK button you are agree in the software agreement !'

$returned = MsgBox(65, 'Info', $MsgText)
If $returned = $IDCANCEL Then
    Exit
Else
    #do nothing
EndIf


#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 339, 131, 192, 124)
$Label1 = GUICtrlCreateLabel("Welcome to the empty frame software :)", 72, 32, 191, 17)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd

You may note that I have used two buttons here but that's not a problem I can be good with one button.

Link to comment
Share on other sites

  • Solution

ok, thanks to @Nine, now you have a UDF file. And call it kind of like MsgBox()

Your script:

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>
#include <MsgBox_Extn.au3> ; the magic ; https://www.autoitscript.com/forum/index.php?showtopic=211499&view=findpost&p=1530323


$MsgText = 'Continue using this software at your own risk !' & @CRLF
$MsgText &= 'By clicking on OK button you are agree in the software agreement !'


#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 339, 131, -1, -1)
$Label1 = GUICtrlCreateLabel("Welcome to the empty frame software :)", 72, 32, 191, 17)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###


;~ $returned = MsgBox(BitOR($MB_TOPMOST, $MB_ICONINFORMATION, $MB_OKCANCEL), 'Info', $MsgText) ; This is replcaced by either

; set any of the 3 possible buttons, from left to right, with an alternate text.
;~ _MsgBox_Extn_SetButtonText(Default, "Run away") ; Each setting applies to a next call only.

; pass 1 value, as the delay countdown:
$returned = _MsgBox_Extn(5, BitOR($MB_TOPMOST, $MB_ICONINFORMATION, $MB_OKCANCEL), 'Info', $MsgText, 0, $Form1)

; or pass 3 comma delimited parameters been: "delay, X pos, Y pos"
;    also, the buttom number to delay, can be chosen by "/2" for the 2nd button for example. Default is Button1.
;~ $returned = _MsgBox_Extn("5/1, 20, 100", BitOR($MB_TOPMOST, $MB_ICONINFORMATION, $MB_OKCANCEL), 'Info', $MsgText, 10, $Form1)

; or pass 3 comma delimited parameters been: "0 delay, X pos, Y pos" to just move the MsgBox
;~ $returned = _MsgBox_Extn("0, 20, 100", BitOR($MB_TOPMOST, $MB_ICONINFORMATION, $MB_OKCANCEL), 'Info', $MsgText, 10, $Form1)

; or pass 5 comma delimited parameters been: "delay, X pos, Y pos, Width, Height" but is in my view, nonsense.
;~ $returned = _MsgBox_Extn("5/-2, 20, 100, 600, 300", BitOR($MB_TOPMOST, $MB_ICONINFORMATION, $MB_OKCANCEL), 'Info', $MsgText, 10, $Form1)

If $returned = $IDCANCEL Then
    GUIDelete()
    Exit 5 ; it exited with an errorlevel of, 5 in this case.
EndIf

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            GUIDelete()
            ExitLoop

    EndSwitch
WEnd


The UDF file:     MsgBox_Extn.au3

Spoiler
#include-once ; #include <MsgBox_Extn.au3>
#include <WinAPISys.au3>
#include <WinAPISysWin.au3> ; do check these include with your current version of AutoIt, it func() not found ( note for the future )
#include <WinAPI.au3>
#include <MsgBoxConstants.au3> ; for the demo

Global Const $g__MsgBox_Extn_tagCBT_CREATEWND = "ptr lpcs;HWND tagCBT_CREATEWND" ; https://www.autoitscript.com/forum/topic/191204-hookdlgbox-udf/
Global Const $g__MsgBox_Extn_tagCREATESTRUCT = "ptr lpCreateParams;handle hInstance;HWND hMenu;HWND hwndParent;int cy;int cx;int y;int x;LONG style;ptr lpszName;ptr lpszClass;DWORD dwExStyle"

Global $g__MsgBox_Extn_Globals_UDFversion = 4, _
        $g__MsgBox_Extn_Globals_hHook = 0, _
        $g__MsgBox_Extn_Globals_DisableAll = 0, _
        $g__MsgBox_Extn_Globals_BttnAtlText[5] = [4, Default, Default, Default, Default], _
        $g__MsgBox_Extn_Globals_DelayOnBttnNo = 1, _
        $g__MsgBox_Extn_Globals_aWinPos = 0, _
        $g__MsgBox_Extn_Globals_iSecCount = 0, _
        $g__MsgBox_Extn_Globals_hWnd = 0, _
        $g__MsgBox_Extn_Globals_hCallBackFunc = Default, _
        $g__MsgBox_Extn_Globals_iDoitOnlyOnce = 1, _
        $g__MsgBox_Extn_Globals_sOriginalText


; same as MsgBox() + timeout [+ button to delay]
;~ _MsgBox_Extn(5, BitOR($MB_TOPMOST, $MB_ICONINFORMATION, $MB_OK), "My title", "My Message", 20)
;~ _MsgBox_Extn("0, 20, 100", BitOR($MB_TOPMOST, $MB_ICONINFORMATION, $MB_OKCANCEL), "My title", "My Message", 20)
;~ _MsgBox_Extn("5/1, 20, 100", BitOR($MB_TOPMOST, $MB_ICONINFORMATION, $MB_YESNO), "My title", "My Message", 20)
;~ _MsgBox_Extn("5 sec. / -4th button, 20, 100, 600, 300", BitOR($MB_TOPMOST, $MB_ICONINFORMATION, $MB_CANCELTRYCONTINUE, $MB_HELP), "My title", "My Message", 20)


;       SecDelay            The time delay until the control is re-enabled ; or a comma delimited string up to "delay [, X pos [, Y pos [, Width [, Height]]]]"
;                               "delay" can be formated as "delay [ /ButtonNumber]". Default is Button1.
;                               if ButtonNumber is a negative number, it'll disable all the buttons.
;       flag                The flag indicates the type of message box and the possible button combinations. See remarks in MsgBox().
;       title               The title of the message box.
;       text                The text of the message box.
;       timeout [optional]  Timeout in seconds. After the timeout has elapsed the message box will close automatically. The default is 0, which is no timeout.
;       hwnd [optional]     The window handle to use as the parent for this dialog.

;   Return Value
;       Success: the ID of the button pressed.
;       Failure: $IDTIMEOUT (-1) if the message box timed out.
;
;       @extended = function misuse

Func _MsgBox_Extn($iSecDelay, $iFlag, $sTitle, $sText, $iSecTimeout = 0, $hParent_hwnd = 0)
    ; https://www.autoitscript.com/forum/index.php?showtopic=211499&view=findpost&p=1530323
    $g__MsgBox_Extn_Globals_aWinPos = StringSplit($iSecDelay, ",")
    ReDim $g__MsgBox_Extn_Globals_aWinPos[6]
    Local $iExt = 0, $aBttnNoDelay = StringSplit(StringReplace($g__MsgBox_Extn_Globals_aWinPos[1], "\", "/"), "/")
    ReDim $aBttnNoDelay[3]
    $g__MsgBox_Extn_Globals_DelayOnBttnNo = Int($aBttnNoDelay[2])
    If Not $g__MsgBox_Extn_Globals_DelayOnBttnNo Then $g__MsgBox_Extn_Globals_DelayOnBttnNo = 1
    If $g__MsgBox_Extn_Globals_DelayOnBttnNo < 0 Then
        $g__MsgBox_Extn_Globals_DisableAll = 1
        $g__MsgBox_Extn_Globals_DelayOnBttnNo = Abs($g__MsgBox_Extn_Globals_DelayOnBttnNo)
    EndIf
    If $g__MsgBox_Extn_Globals_DelayOnBttnNo > 4 Then
        $g__MsgBox_Extn_Globals_DelayOnBttnNo = 1
        $iExt = 2 ; function misuse ; no more than a 4th button.
    EndIf

    If $g__MsgBox_Extn_Globals_aWinPos[0] > 5 Then
        $g__MsgBox_Extn_Globals_aWinPos[0] = 5 ; better safe than sorry.
        $iExt = 1 ; function misuse ; $iSecDelay = "delay [, X pos [, Y pos [, Width [, Height]]]]" only.
    EndIf

    For $n = 1 To $g__MsgBox_Extn_Globals_aWinPos[0]
        $g__MsgBox_Extn_Globals_aWinPos[1] = Int($g__MsgBox_Extn_Globals_aWinPos[1])
    Next
    For $n = $g__MsgBox_Extn_Globals_aWinPos[0] + 1 To 5
        $g__MsgBox_Extn_Globals_aWinPos[$n] = Null ; these are unused place holders.
    Next
    Local $hTimerProc = DllCallbackRegister(__MsgBox_Extn_TimerProc, 'none', 'hwnd;uint;uint_ptr;dword')
    Local $iTimerID = _WinAPI_SetTimer(0, 0, 1000, DllCallbackGetPtr($hTimerProc)) ; $iTimerID should be 0 if the $hWnd is 0.
    Local $hProc = DllCallbackRegister(__MsgBox_Extn_CbtHookProc, "int", "int;int;int")
    $g__MsgBox_Extn_Globals_hHook = _WinAPI_SetWindowsHookEx($WH_CBT, DllCallbackGetPtr($hProc), 0, _WinAPI_GetCurrentThreadId())
    Local $iRet = MsgBox($iFlag, $sTitle, $sText, $iSecTimeout, $hParent_hwnd)
    _WinAPI_KillTimer(0, $iTimerID)
    DllCallbackFree($hTimerProc)
    _WinAPI_UnhookWindowsHookEx($g__MsgBox_Extn_Globals_hHook)
    DllCallbackFree($hProc)
    $g__MsgBox_Extn_Globals_hHook = 0
    $g__MsgBox_Extn_Globals_iSecCount = 0
    $g__MsgBox_Extn_Globals_aWinPos = 0
    $g__MsgBox_Extn_Globals_hWnd = 0
    $g__MsgBox_Extn_Globals_iDoitOnlyOnce = 1
    $g__MsgBox_Extn_Globals_DelayOnBttnNo = 1
    $g__MsgBox_Extn_Globals_DisableAll = 0
    _MsgBox_Extn_SetButtonText() ; re-init all prior alternate button text to defaults.
    Return SetError(0, $iExt, $iRet)
EndFunc   ;==>_MsgBox_Extn

; Returns the UDF version. Just in case more stuff is added.
Func _MsgBox_Extn_Version()
    Return $g__MsgBox_Extn_Globals_UDFversion
EndFunc   ;==>_MsgBox_Extn_Version

; Set any of the 4 possible buttons, from left to right, with an alternate text.
Func _MsgBox_Extn_SetButtonText($iButton1 = Default, $iButton2 = Default, $iButton3 = Default, $iButton4 = Default)
    $g__MsgBox_Extn_Globals_BttnAtlText[1] = $iButton1
    $g__MsgBox_Extn_Globals_BttnAtlText[2] = $iButton2
    $g__MsgBox_Extn_Globals_BttnAtlText[3] = $iButton3
    $g__MsgBox_Extn_Globals_BttnAtlText[4] = $iButton4
EndFunc   ;==>_MsgBox_Extn_SetButtonText

; After _MsgBox_Extn_SetButtonText(), you'll need to _MsgBox_Extn_ApplyButtonText() if _MsgBox_Extn_SetCallBackFunc() is used.
Func _MsgBox_Extn_ApplyButtonText()
    For $n = 1 To $g__MsgBox_Extn_Globals_BttnAtlText[0]
        If Not IsKeyword($g__MsgBox_Extn_Globals_BttnAtlText[$n]) Then
            ControlSetText($g__MsgBox_Extn_Globals_hWnd, "", "Button" & $n, String($g__MsgBox_Extn_Globals_BttnAtlText[$n]), 1)
        EndIf
    Next
EndFunc   ;==>_MsgBox_Extn_ApplyButtonText

; Set a new message text on the fly via _MsgBox_Extn_SetCallBackFunc()
Func _MsgBox_Extn_SetMessageText($sStr)
    Local $iRet, $iStatic = 2
    If ControlGetText($g__MsgBox_Extn_Globals_hWnd, "", "Static2") = "" Or @error Then $iStatic = 1
    $iRet = ControlSetText($g__MsgBox_Extn_Globals_hWnd, "", "Static" & $iStatic, String($sStr))
    Return SetError(Int(Not $iRet), $iStatic, $iRet)
EndFunc   ;==>_MsgBox_Extn_SetMessageText

; Set a new default text on the fly via _MsgBox_Extn_SetCallBackFunc()
Func _MsgBox_Extn_SetCounterButtonText($sNewText = Default)
    If Not IsKeyword($sNewText) Then $g__MsgBox_Extn_Globals_sOriginalText = String($sNewText)
    Return $g__MsgBox_Extn_Globals_sOriginalText
EndFunc   ;==>_MsgBox_Extn_SetCounterButtonText

; Set a new count down on the fly via _MsgBox_Extn_SetCallBackFunc()
Func _MsgBox_Extn_SecCount($iNewValue = Default)
    If Not IsKeyword($iNewValue) Then
        $g__MsgBox_Extn_Globals_aWinPos[1] = Int($iNewValue)
        $g__MsgBox_Extn_Globals_iSecCount = -1
    EndIf
    Return $g__MsgBox_Extn_Globals_aWinPos[1] - $g__MsgBox_Extn_Globals_iSecCount
EndFunc   ;==>_MsgBox_Extn_SecCount

; The handle of the MsgBox(), to use in _MsgBox_Extn_SetCallBackFunc()
Func _MsgBox_Extn_GetHWnd()
    Return $g__MsgBox_Extn_Globals_hWnd
EndFunc   ;==>_MsgBox_Extn_GetHWnd

; To do stuff within the time the delay is active.
; example at https://www.autoitscript.com/forum/index.php?showtopic=211499&view=findpost&p=1530455
Func _MsgBox_Extn_SetCallBackFunc($hCallBackFunc = Null) ; a no parameter func(). Use helper func ( _MsgBox_Extn_* )
;~  ConsoleWrite('+ Func _MsgBox_Extn_SetCallBackFunc("' & FuncName($hCallBackFunc) & '")' & @CRLF)
    If IsFunc($hCallBackFunc) Then
        $g__MsgBox_Extn_Globals_hCallBackFunc = $hCallBackFunc
    ElseIf IsKeyword($hCallBackFunc) = 1 Then ; $KEYWORD_DEFAULT (1) the Default keyword. ; $KEYWORD_NULL (2) the Null keyword.
        $g__MsgBox_Extn_Globals_hCallBackFunc = ""
    EndIf
    Return $g__MsgBox_Extn_Globals_hCallBackFunc
EndFunc   ;==>_MsgBox_Extn_SetCallBackFunc


#Region INTERNAL

Func __MsgBox_Extn_TimerProc($hWnd, $iMsg, $iTimerID, $iTime)
;~  ConsoleWrite('+ Func __MsgBox_Extn_TimerProc(' & $hWnd & ', ' & $iMsg & ', ' & $iTimerID & ', ' & $iTime & ')' & @CRLF)
    #forceref $hWnd, $iMsg, $iTimerID, $iTime
    $g__MsgBox_Extn_Globals_iSecCount += 1
    If $g__MsgBox_Extn_Globals_iSecCount < $g__MsgBox_Extn_Globals_aWinPos[1] Then
        ControlSetText($g__MsgBox_Extn_Globals_hWnd, "", "Button" & $g__MsgBox_Extn_Globals_DelayOnBttnNo, $g__MsgBox_Extn_Globals_aWinPos[1] - $g__MsgBox_Extn_Globals_iSecCount)
    ElseIf $g__MsgBox_Extn_Globals_iSecCount = $g__MsgBox_Extn_Globals_aWinPos[1] Then
        ControlSetText($g__MsgBox_Extn_Globals_hWnd, "", "Button" & $g__MsgBox_Extn_Globals_DelayOnBttnNo, _MsgBox_Extn_SetCounterButtonText())
        If $g__MsgBox_Extn_Globals_DisableAll Then
            For $n = 1 To 4
                ControlEnable($g__MsgBox_Extn_Globals_hWnd, "", "Button" & $n)
            Next
        Else
            ControlEnable($g__MsgBox_Extn_Globals_hWnd, "", "Button" & $g__MsgBox_Extn_Globals_DelayOnBttnNo)
        EndIf
    EndIf
    If IsFunc($g__MsgBox_Extn_Globals_hCallBackFunc) Then $g__MsgBox_Extn_Globals_hCallBackFunc() ; $hWnd, $iMsg, $iTimerID, $iTime) ; there's no use for these.
EndFunc   ;==>__MsgBox_Extn_TimerProc

Func __MsgBox_Extn_CbtHookProc($nCode, $wParam, $lParam)
;~  ConsoleWrite('+ Func __MsgBox_Extn_CbtHookProc(' & $nCode & ', ' & $wParam & ', ' & $lParam & ')' & @CRLF)
    If $nCode = 3 And $g__MsgBox_Extn_Globals_iDoitOnlyOnce = 1 And _WinAPI_GetClassName(HWnd($wParam)) = "#32770" Then
        $g__MsgBox_Extn_Globals_iDoitOnlyOnce = 2
        $g__MsgBox_Extn_Globals_hWnd = HWnd($wParam)
        If $g__MsgBox_Extn_Globals_aWinPos[2] <> Null Then
            Local $tcs = DllStructCreate($g__MsgBox_Extn_tagCREATESTRUCT, DllStructGetData(DllStructCreate($g__MsgBox_Extn_tagCBT_CREATEWND, $lParam), "lpcs"))
            If $g__MsgBox_Extn_Globals_aWinPos[2] <> Null Then DllStructSetData($tcs, "x", $g__MsgBox_Extn_Globals_aWinPos[2])
            If $g__MsgBox_Extn_Globals_aWinPos[3] <> Null Then DllStructSetData($tcs, "y", $g__MsgBox_Extn_Globals_aWinPos[3])
            If $g__MsgBox_Extn_Globals_aWinPos[4] <> Null Then DllStructSetData($tcs, "cx", $g__MsgBox_Extn_Globals_aWinPos[4]) ; these Cx,Cy don't do anything functional
            If $g__MsgBox_Extn_Globals_aWinPos[5] <> Null Then DllStructSetData($tcs, "cy", $g__MsgBox_Extn_Globals_aWinPos[5]) ;        but, you can use them if you wish.
        EndIf
    EndIf
    If $nCode = 5 And $g__MsgBox_Extn_Globals_iDoitOnlyOnce = 2 And $g__MsgBox_Extn_Globals_aWinPos[1] > 0 And HWnd($wParam) = $g__MsgBox_Extn_Globals_hWnd Then ; 5=HCBT_ACTIVATE
        $g__MsgBox_Extn_Globals_iDoitOnlyOnce = 0
        _MsgBox_Extn_ApplyButtonText()
        If $g__MsgBox_Extn_Globals_DisableAll Then
            For $n = 1 To 4
                ControlDisable($g__MsgBox_Extn_Globals_hWnd, "", "Button" & $n)
            Next
        Else
            ControlDisable($g__MsgBox_Extn_Globals_hWnd, "", "Button" & $g__MsgBox_Extn_Globals_DelayOnBttnNo)
        EndIf
        _MsgBox_Extn_SetCounterButtonText(ControlGetText($g__MsgBox_Extn_Globals_hWnd, "", "Button" & $g__MsgBox_Extn_Globals_DelayOnBttnNo))
        ControlSetText($g__MsgBox_Extn_Globals_hWnd, "", "Button" & $g__MsgBox_Extn_Globals_DelayOnBttnNo, $g__MsgBox_Extn_Globals_aWinPos[1])
    ElseIf $nCode = 5 And $g__MsgBox_Extn_Globals_iDoitOnlyOnce = 2 And HWnd($wParam) = $g__MsgBox_Extn_Globals_hWnd Then
        _MsgBox_Extn_ApplyButtonText()
    EndIf
    Return _WinAPI_CallNextHookEx($g__MsgBox_Extn_Globals_hHook, $nCode, $wParam, $lParam)
EndFunc   ;==>__MsgBox_Extn_CbtHookProc

#EndRegion INTERNAL

 

image.png.b87ba02f4575bb190c2a635c7724a2d7.png

There you go.

Edit: Fixed "Run Once", never running again.
Edit2: Fixed button, not restoring the original text.
Edit3: Added X,Y  "WinMove()".
Edit4: Fixed when delay is zero because the user just wants to move the MsgBox().
Edit5: Changed the name to a more fitting one.
Edit6: Added to optionally choose the button to disable.
Edit7: Added to optionally change a default button text.
Edit8: Fixed stuff and added stuff. ( Example for some of new stuff provided )

Spoiler
#include <MsgBox_Extn.au3> ; https://www.autoitscript.com/forum/index.php?showtopic=211499&view=findpost&p=1530323

Exit Example_CallBack()
Func Example_CallBack()
    Local $MsgText = 'Now this example will punish you' & @CR & 'by wasting 60 seconds of your life.'
    _MsgBox_Extn_SetCallBackFunc(_MyCallBack_TimerProc)
    ConsoleWrite('using "' & FuncName(_MsgBox_Extn_SetCallBackFunc()) & '()" as callback function.' & @CRLF)
    Local $iRet = _MsgBox_Extn("60/-1", BitOR($MB_OK, $MB_HELP), 'Example', $MsgText)
    _MsgBox_Extn_SetCallBackFunc(Default) ; if you're not gonna use it anymore.
    Return $iRet
EndFunc   ;==>Example_CallBack

Func _MyCallBack_TimerProc()
    If _MsgBox_Extn_SecCount() = 55 Then
        ConsoleWrite('MsgBox HWnd: ' & _MsgBox_Extn_GetHWnd() & @CRLF)
        ConsoleWrite('UDF version: ' & _MsgBox_Extn_Version() & @CRLF)
        _MsgBox_Extn_SecCount(3)
        _MsgBox_Extn_SetMessageText('Nah, just kidding  =)')
        _MsgBox_Extn_SetButtonText(Default, "No help ?")
        _MsgBox_Extn_ApplyButtonText()
    EndIf
EndFunc   ;==>_MyCallBack_TimerProc

 

Edit9: Added _MsgBox_Extn_SetMessageText()
Edit10: Added "disable all buttons", if the 2nd number is a negative   (" 5 sec. / -1 ButtonNumber ", .
Edit11: Removed callback parameters in function. This is simpler.

Edited by argumentum
better code ?

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

Thank you guys you have really did a great work !

 

11 minutes ago, argumentum said:

..if he wanted the MsgBox centered in his GUI, I'd have used chucks of yours too :) 

I would suggest to make message box centered since this will make it more correctly print in different screens.

Link to comment
Share on other sites

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>

#include <MsgBox_Extn.au3> ; the magic

$MsgText = 'Continue using this software at your own risk !' & @CRLF
$MsgText &= 'By clicking on OK button you are agree in the software agreement !'


#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 339, 131, -1, -1)
$Label1 = GUICtrlCreateLabel("Welcome to the empty frame software :)", 72, 32, 191, 17)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###


;~ $returned = MsgBox(65, 'Info', $MsgText)
$returned = _MsgBox_Extn(5, 65, 'Info', $MsgText, 0, $Form1)
If $returned = $IDCANCEL Then
    GUIDelete()
    Exit
Else
    #do nothing
EndIf

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd

image.png.31b1f3190546df6ffefa58b4944917d4.png

I hope that's good enough :P

Edited by argumentum
renamed function

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

...what do people with insomnia do ?. Code 🤪
Added WinMove the MsgBox() to, anywhere. Center it on you GUI if the GUI is not centered ?

And renamed the UDF and function. It does more and quite likely, will have more use as a box mover, than the original timer delay aspect of it. 

Edited by argumentum
renamed everything

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

14 hours ago, SmOke_N said:

My goodness, ya'll are murderfying my script lol.

..you know, going down the rabbits hole, at trying to add "SetDlgItemText" to rename the buttons, might as well just have added the timer thing to your script. 😅

Edit: ..the idea started after reading https://uxmovement.com/buttons/why-the-ok-button-is-no-longer-okay/ and I'm like, meh, I'll add that too. Wrong.

Edited by argumentum
more

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...