Leaderboard
Popular Content
Showing content with the highest reputation on 02/19/2024 in all areas
-
MsgBox_Extn() UDF
ioa747 reacted to argumentum for a topic
It started in the help area, to delay the OK button for X seconds but is a good example for a mix of _WinAPI_SetTimer(), _WinAPI_SetWindowsHookEx(), IsFunc(), FuncName() and a callback. ; same as MsgBox() + button to delay[ /options ] [+ X,Y,W,H ] _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) The use is simple ( to me that I wrote it ). Try the examples above and it'll be self evident. Is a MsgBox with an extra ( 1st ) parameter. All expected returns are the same. But in @error there is also the return value and in @extended the line number were something is wrong. I may start coding this way for myself too. Is like a UDF with training wheels. A fun example of the callback is: #include <MsgBox_Extn.au3> ; https://www.autoitscript.com/forum/index.php?showtopic=211523 ConsoleWrite(@CRLF & "+++ _MsgBox_Extn() returned: $" & _MsgBox_Extn_ReturnMeaning(Example_CallBack(4)) & ' (' & @extended & ')' & @CRLF & @CRLF) ConsoleWrite('==========------------==========------------==========------------==========------------==========------------==========') ConsoleWrite(@CRLF & "+++ _MsgBox_Extn() returned: $" & _MsgBox_Extn_ReturnMeaning(Example_CallBack(1)) & ' (' & @extended & ')' & @CRLF & @CRLF) Func Example_CallBack($iTryButton) If _MsgBox_Extn_Version() < 5 Then Return SetError(1, 0, -2) Local $MsgText = 'Now this example will punish you' & @CR & 'by wasting 60 seconds of your life.' _MsgBox_Extn_SetCallBackFunc(_MyCallBack_TimerProc) If @error Then Return SetError(2, 0, -2) ConsoleWrite('+++ Using "' & FuncName(_MsgBox_Extn_SetCallBackFunc()) & '" as callback function.' & @CRLF) Local $iMisuseAtLineNumber, $iRet = _MsgBox_Extn("60/-" & $iTryButton, BitOR($MB_OKCANCEL, $MB_HELP), 'Example', $MsgText, 15) ; "-4" is wrong. Part of the demo. $iReturn = @error $iMisuseAtLineNumber = @extended ; so misuse/error, can be gathered for debug. If $iMisuseAtLineNumber Then ConsoleWrite('! At line ' & $iMisuseAtLineNumber & ' in the UDF, there was a complain. ( Naggy UDF ! )' & @CRLF) ConsoleWrite('@error (' & $iReturn & ') holds the same value as Return (' & $iRet & '). Why ?, meh, it may come in handy.' & _ ' There is no error return in MsgBox. Let''s give it some use.' & @CRLF) _MsgBox_Extn_SetCallBackFunc(Default) ; if you're not gonna use it anymore. Return $iRet EndFunc ;==>Example_CallBack Func _MyCallBack_TimerProc() Switch _MsgBox_Extn_SecCount() Case 60 ConsoleWrite('UDF version: ' & _MsgBox_Extn_Version() & @CRLF) Case 58 ; With the MsgBox HWnd, you can have your fun. ControlEnable(_MsgBox_Extn_GetHWnd(), "", "Button2") Case 57 _MsgBox_Extn_SetMessageText('Nah, just kidding =)') _MsgBox_Extn_SecCount(3) _MsgBox_Extn_SetCounterButtonText(_MsgBox_Extn_SetCounterButtonText() & " ?") Case 1 ; Setting "SetCounterButtonText" is used on a next loop. In 1 second. _MsgBox_Extn_SetCounterButtonText(_MsgBox_Extn_GetOrigBttnText()) Case 0 _MsgBox_Extn_SetButtonText(Default, Default, _MsgBox_Extn_GetOrigBttnText( _MsgBox_Extn_TotalCount()) & " ???") _MsgBox_Extn_ApplyButtonText() EndSwitch EndFunc ;==>_MyCallBack_TimerProc and the UDF code: #include-once ; #include <MsgBox_Extn.au3> ; https://www.autoitscript.com/forum/index.php?showtopic=211523 #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 Const $g__MsgBox_Extn_aReturnMeaning[13] = [11, "IDOK", "IDCANCEL", "IDABORT", "IDRETRY", "IDIGNORE", "IDYES", "IDNO", "ID#8", "ID#9", "IDTRYAGAIN", "IDCONTINUE", "IDTIMEOUT"] Global $g__MsgBox_Extn_Globals_UDFversion = 5, _ $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_BttnOriText[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_BttnOriCount = 0, _ $g__MsgBox_Extn_Globals_iWarning = 0, _ $g__MsgBox_Extn_Globals_sOriginalText ; same as MsgBox() + button to delay[ /options ] [+ X,Y,W,H ] ;~ _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 $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 _MsgBox_Extn_ConsoleWrite('Note: Button' & $g__MsgBox_Extn_Globals_DelayOnBttnNo & ' will not exist. Setting to Button1 to, be nice ?. Check the code.' & @CRLF) $g__MsgBox_Extn_Globals_DelayOnBttnNo = 1 ; function misuse ; no more than a 4th button. EndIf If $g__MsgBox_Extn_Globals_aWinPos[0] > 5 Then _MsgBox_Extn_ConsoleWrite('Note: ' & $g__MsgBox_Extn_Globals_aWinPos[0] & ' parameters are too many. Check the code.' & @CRLF) $g__MsgBox_Extn_Globals_aWinPos[0] = 5 ; better safe than sorry. ; 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) Local $iExt = $g__MsgBox_Extn_Globals_iWarning $g__MsgBox_Extn_Globals_iWarning = 0 $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 Dim $g__MsgBox_Extn_Globals_BttnOriText[5] = [4, Default, Default, Default, Default] _MsgBox_Extn_SetButtonText() ; re-init all prior alternate button text to defaults. $g__MsgBox_Extn_Globals_BttnOriCount = 0 Return SetError($iRet, $iExt, $iRet) EndFunc ;==>_MsgBox_Extn ; Return the meaning/name of the enumerator/constant Func _MsgBox_Extn_ReturnMeaning($iIndex) $iIndex = Int($iIndex) If $iIndex = -1 Then Return SetExtended($iIndex, $g__MsgBox_Extn_aReturnMeaning[12]) Switch $iIndex Case 8, 9 Return SetError(1, $iIndex, "unkown index " & $iIndex) Case 1 To 12 Return SetExtended($iIndex, $g__MsgBox_Extn_aReturnMeaning[$iIndex]) EndSwitch Return SetError(2, $iIndex, "unkown index " & $iIndex) EndFunc ;==>_MsgBox_Extn_ReturnMeaning ; 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 ; Get the original text of any of the 4 possible buttons. ; For if _MsgBox_Extn_SetCallBackFunc() is used. Func _MsgBox_Extn_GetOrigBttnText($iIndex = $g__MsgBox_Extn_Globals_DelayOnBttnNo) If $iIndex > 4 Or $iIndex < 1 Then $g__MsgBox_Extn_Globals_iWarning = @ScriptLineNumber _MsgBox_Extn_ConsoleWrite('Note: an $iIndex of ' & $iIndex & ' should have been between 1 and 4. Therefore is an error.' & @CRLF) $iIndex = $g__MsgBox_Extn_Globals_DelayOnBttnNo EndIf Return SetExtended(IsKeyword($g__MsgBox_Extn_Globals_BttnOriText[$iIndex]), $g__MsgBox_Extn_Globals_BttnOriText[$iIndex]) EndFunc ;==>_MsgBox_Extn_GetOrigBttnText ; Reset the original text of the 4 possible buttons. Or just the one you pass along as Index. ; For if _MsgBox_Extn_SetCallBackFunc() is used. Func _MsgBox_Extn_ResetButtonText($iIndex = Default) If IsKeyword($iIndex) = 1 Then For $n = 1 To $g__MsgBox_Extn_Globals_BttnOriText[0] $g__MsgBox_Extn_Globals_BttnAtlText[$n] = $g__MsgBox_Extn_Globals_BttnOriText[$n] Next Else If $iIndex > 4 Or $iIndex < 1 Then $g__MsgBox_Extn_Globals_iWarning = @ScriptLineNumber _MsgBox_Extn_ConsoleWrite('Note: an $iIndex of ' & $iIndex & ' should have been between 1 and 4. Therefore is an error.' & @CRLF) $iIndex = $g__MsgBox_Extn_Globals_DelayOnBttnNo EndIf $g__MsgBox_Extn_Globals_BttnAtlText[$n] = $g__MsgBox_Extn_Globals_BttnOriText[$n] EndIf EndFunc ;==>_MsgBox_Extn_ResetButtonText ; 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() ; For use in _MsgBox_Extn_SetCallBackFunc() 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 ; For use in _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 ; For use in _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 Func _MsgBox_Extn_TotalCount() Return $g__MsgBox_Extn_Globals_BttnOriCount EndFunc ;==>_MsgBox_Extn_TotalCount ; 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 Func _MsgBox_Extn_ConsoleWrite($sStr, $iLineNumber = @ScriptLineNumber) Local Static $iReturn = Not (StringRight(@ScriptName, 4) = '.au3') $g__MsgBox_Extn_Globals_iWarning = $iLineNumber If $iReturn Then Return "" ConsoleWrite('"MsgBox_Extn.au3" (' & $iLineNumber & ',0) : ' & $sStr) EndFunc ;==>_MsgBox_Extn_ConsoleWrite ; 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_* ) Local $iErr = 0 If IsKeyword($hCallBackFunc) = 1 Then ; $KEYWORD_DEFAULT (1) the Default keyword. ; $KEYWORD_NULL (2) the Null keyword. $g__MsgBox_Extn_Globals_hCallBackFunc = "" ; ..to remove the value ElseIf IsFunc($hCallBackFunc) Then $g__MsgBox_Extn_Globals_hCallBackFunc = $hCallBackFunc ElseIf IsKeyword($hCallBackFunc) = 2 Then ; This is to return the $hCallBackFunc in use. Else ; if we get to this point, is not a keyword nor a function. Therefore is an error. _MsgBox_Extn_ConsoleWrite('Note: If we get to this point, is not a keyword nor a function. Therefore is an error.' & @CRLF) $g__MsgBox_Extn_Globals_hCallBackFunc = "" ; since is an error, let's remove whatever was there. $iErr = 1 EndIf Return SetError($iErr, 0, $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, _MsgBox_Extn_SetCounterButtonText() & ' (' & $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 For $n = 1 To 4 $g__MsgBox_Extn_Globals_BttnOriText[$n] = ControlGetText($g__MsgBox_Extn_Globals_hWnd, "", "Button" & $n) If $g__MsgBox_Extn_Globals_BttnOriText[$n] = "" And @error Then If Not $g__MsgBox_Extn_Globals_BttnOriCount Then $g__MsgBox_Extn_Globals_BttnOriCount = $n - 1 $g__MsgBox_Extn_Globals_BttnOriText[$n] = Default EndIf Next If $g__MsgBox_Extn_Globals_DelayOnBttnNo > $g__MsgBox_Extn_Globals_BttnOriCount Then _MsgBox_Extn_ConsoleWrite('Note: Button' & $g__MsgBox_Extn_Globals_DelayOnBttnNo & ' does not exist on this ' & $g__MsgBox_Extn_Globals_BttnOriCount & ' button MsgBox. Setting to Button1. Check the code.' & @CRLF) $g__MsgBox_Extn_Globals_DelayOnBttnNo = 1 EndIf _MsgBox_Extn_SetCounterButtonText(_MsgBox_Extn_GetOrigBttnText($g__MsgBox_Extn_Globals_DelayOnBttnNo)) ControlSetText($g__MsgBox_Extn_Globals_hWnd, "", "Button" & $g__MsgBox_Extn_Globals_DelayOnBttnNo, _MsgBox_Extn_SetCounterButtonText() & ' (' & $g__MsgBox_Extn_Globals_aWinPos[1] & ')') If IsFunc($g__MsgBox_Extn_Globals_hCallBackFunc) Then $g__MsgBox_Extn_Globals_hCallBackFunc() 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 And a $MB_HELP usage example ( somewhere down there ). If you don't feel like copy and paste all this then here: MsgBox_Extn[v5].zip In version 5 there more stuff. Lost count, but it has nagging code to let the user know, if the code has a complain about the parameters. So, this is a good example as far as examples but M23's Extended Message Box is a better option if you need a flexible MsgBox UDF.1 point -
You could try something like this, but I'm not sure that you will be any happier with the result -- ConsoleWrite("Error Creating Session: " & $aWD_ERROR_DESC[@error] & " Exiting." & @CRLF) FYI, there is a pending patch to deal with Google once again changing the Chromedriver location.1 point
-
WebDriver is drivering me crazy
taurus905 reacted to SOLVE-SMART for a topic
Hi @MarcoMonte 👋 , let's try something: Usually I recommend further reading of the different documentations like the WebDriver wiki page or all the links on the au3WebDriver repository, but this time I am curious wheater the following could help you for a quick start or not. Actually I created this for some german forum members, but I guess you could also benefit from it: Please check out my repository au3webdriver-boilerplate which should help you starting your webdriver actions. In case you're familiar with GitHub, just clone the repo and go ahead (by reading the README.md file). Otherwise download the release (zip), and start there (by reading the README.md file). Please let me know if this is helpful in any way or even if not, what can I improve 🤝 . Best regards Sven1 point -
@CYCho the quotation marks really solve the problem, but if you use FileGetShortName() even placing quotation marks does not work in this version of winmm.dll which caused the problem.1 point
-
1 point
-
I meant something like this here (proof of concept): #include <GDIPlus.au3> Global Const $CELL_SIZE = 30 Global Const $GRID_PADDING = 5 Global Const $MIN_CIRCLE_RADIUS = 5 Global Const $MAX_CIRCLE_RADIUS = 10 Global $START = TimerInit() Func DrawCircles($hGraphics,$GRID_SIZE) Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF5050) For $i = 0 To $GRID_SIZE - 1 For $j = 0 To $GRID_SIZE - 1 Local $iRadius = Random($MIN_CIRCLE_RADIUS, $MAX_CIRCLE_RADIUS, 1) Local $iCenterX = $GRID_PADDING * 1.5 + $j * ($CELL_SIZE + $GRID_PADDING) + $CELL_SIZE / 2 Local $iCenterY = $GRID_PADDING * 1.5 + $i * ($CELL_SIZE + $GRID_PADDING) + $CELL_SIZE / 2 _GDIPlus_GraphicsFillEllipse($hGraphics, $iCenterX - $iRadius, $iCenterY - $iRadius, $iRadius * 2, $iRadius * 2, $hBrush) Next Next _GDIPlus_BrushDispose($hBrush) EndFunc ;==>DrawCircles Func DrawGrid($hGraphics,$GRID_SIZE) Local $hPen = _GDIPlus_PenCreate(0xFF000000, 1) For $i = 0 To $GRID_SIZE Local $iX = $i * ($CELL_SIZE + $GRID_PADDING) _GDIPlus_GraphicsDrawLine($hGraphics, $GRID_PADDING, $GRID_PADDING + $iX, $GRID_PADDING + $GRID_SIZE * ($CELL_SIZE + $GRID_PADDING), $GRID_PADDING + $iX, $hPen) _GDIPlus_GraphicsDrawLine($hGraphics, $GRID_PADDING + $iX, $GRID_PADDING, $GRID_PADDING + $iX, $GRID_PADDING + $GRID_SIZE * ($CELL_SIZE + $GRID_PADDING), $hPen) Next _GDIPlus_PenDispose($hPen) EndFunc ;==>DrawGrid Func DrawGridToBitmap($GRID_SIZE) $aWS = ProcessGetStats() Local $pb = Round($aWS[1]/1024/1024) _GDIPlus_Startup() Local $iW = $GRID_SIZE * ($CELL_SIZE + $GRID_PADDING) + 2*$GRID_PADDING + 1, $iH = $GRID_SIZE * ($CELL_SIZE + $GRID_PADDING) + 2*$GRID_PADDING + 1 ;~ ConsoleWrite($iW & " x " & $iH & @CRLF) Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetSmoothingMode($hBmpCtxt, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hBmpCtxt, 0xFFFFFFFF) If $GRID_SIZE > 10 Then Local $iW2 = 10 * ($CELL_SIZE + $GRID_PADDING) + 2*$GRID_PADDING - 1, $iH2 = 10 * ($CELL_SIZE + $GRID_PADDING) + 2*$GRID_PADDING - 1 Local $hBitmap2 = _GDIPlus_BitmapCreateFromScan0($iW2, $iH2), $hBmpCtxt2 = _GDIPlus_ImageGetGraphicsContext($hBitmap2) _GDIPlus_GraphicsClear($hBmpCtxt2, 0xFFFFFFFF) _GDIPlus_GraphicsSetSmoothingMode($hBmpCtxt2, $GDIP_SMOOTHINGMODE_HIGHQUALITY) DrawGrid($hBmpCtxt2,10) DrawCircles($hBmpCtxt2,10) Local $hTexture = _GDIPlus_TextureCreate2($hBitmap2, 5, 5, $iW2 - 9, $iH2 - 9) DllCall($__g_hGDIPDll, "int", "GdipTranslateTextureTransform", "handle", $hTexture, "float", 5, "float", 5, "int", 0) _GDIPlus_GraphicsFillRect($hBmpCtxt, 5, 5, $iW - 11, $iH - 11, $hTexture) _GDIPlus_GraphicsDispose($hBmpCtxt2) _GDIPlus_BitmapDispose($hBitmap2) _GDIPlus_BrushDispose($hTexture) Else DrawGrid($hBmpCtxt,$GRID_SIZE) DrawCircles($hBmpCtxt,$GRID_SIZE) EndIf Local $sFilePath = @ScriptDir & "\grid" & $GRID_SIZE & ".png" _GDIPlus_ImageSaveToFile($hBitmap, $sFilePath) _GDIPlus_GraphicsDispose($hBmpCtxt) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() $aWS = ProcessGetStats() Local $pa = Round($aWS[1]/1024/1024) ConsoleWrite("Runtime: " & Round(TimerDiff($START)/1000) & " seconds.Memory peaks " & $pb & " -> " & $pa & " MB" & @LF) $START = TimerInit() Return $sFilePath EndFunc ;==>DrawGridToBitmap ConsoleWrite("Grid 10 - image created " & DrawGridToBitmap(10) & @LF) ConsoleWrite("Grid 100 - Image created " & DrawGridToBitmap(100) & @LF) ConsoleWrite("Grid 250 - Image created " & DrawGridToBitmap(250) & @LF) ConsoleWrite("Grid 450 - Image created " & DrawGridToBitmap(450) & @LF) ConsoleWrite("Grid 500 - Image created " & DrawGridToBitmap(500) & @LF) ConsoleWrite("Grid 1000 - Image created " & DrawGridToBitmap(1000) & @LF)1 point
-
I assume he will use some real data for/instead of these circles and it's not interested to repeat a pattern. Also you have some minor issue with the output file, it's 15005x15005 px.1 point
-
Merge/copy on my PC gets 2.78 sec for 500x500 on 30 px...including save On creation only < 1 sec. #include <GDIPlus.au3> Local $hTimer = TimerInit() Global Const $CELL_SIZE = 30 Global Const $MIN_CIRCLE_RADIUS = 5 Global Const $MAX_CIRCLE_RADIUS = 10 _GDIPlus_Startup() Local $iMerge = 5 Local $hBitmap = DrawGridToBitmap(100) Local $iDim = _GDIPlus_ImageGetWidth($hBitmap) Local $hImage = _GDIPlus_BitmapCreateFromScan0(($iDim - 1) * $iMerge + 1, ($iDim - 1) * $iMerge + 1) If @error Then Exit ConsoleWrite(@error & @CRLF) Local $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage) For $i = 0 To $iMerge - 1 For $j = 0 To $iMerge - 1 _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, $i * ($iDim - ($i ? 1 : 0)), $j * ($iDim - ($j ? 1 : 0)), $iDim, $iDim) Next Next ConsoleWrite("Creation = " & TimerDiff($hTimer) & @CRLF) _GDIPlus_ImageSaveToFile($hImage, "Test.jpg") _GDIPlus_ImageDispose($hBitmap) _GDIPlus_ImageDispose($hImage) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() ConsoleWrite("Final = " & TimerDiff($hTimer) & @CRLF) Func DrawCircles($hGraphics, $GRID_SIZE) Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF5050) For $i = 0 To $GRID_SIZE - 1 For $j = 0 To $GRID_SIZE - 1 Local $iRadius = Random($MIN_CIRCLE_RADIUS, $MAX_CIRCLE_RADIUS, 1) Local $iCenterX = $j * $CELL_SIZE + $CELL_SIZE / 2 Local $iCenterY = $i * $CELL_SIZE + $CELL_SIZE / 2 _GDIPlus_GraphicsFillEllipse($hGraphics, $iCenterX - $iRadius, $iCenterY - $iRadius, $iRadius * 2, $iRadius * 2, $hBrush) Next Next _GDIPlus_BrushDispose($hBrush) EndFunc ;==>DrawCircles Func DrawGrid($hGraphics, $GRID_SIZE) Local $hPen = _GDIPlus_PenCreate(0xFF000000, 1) For $i = 0 To $GRID_SIZE _GDIPlus_GraphicsDrawLine($hGraphics, 0, $i * $CELL_SIZE, $GRID_SIZE * $CELL_SIZE, $i * $CELL_SIZE, $hPen) _GDIPlus_GraphicsDrawLine($hGraphics, $i * $CELL_SIZE, 0, $i * $CELL_SIZE, $GRID_SIZE * $CELL_SIZE, $hPen) Next _GDIPlus_PenDispose($hPen) EndFunc ;==>DrawGrid Func DrawGridToBitmap($GRID_SIZE) Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($GRID_SIZE * $CELL_SIZE + 1, $GRID_SIZE * $CELL_SIZE + 1) Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hGraphics, 0xFFFFFFFF) DrawGrid($hGraphics, $GRID_SIZE) DrawCircles($hGraphics, $GRID_SIZE) _GDIPlus_GraphicsDispose($hGraphics) Return $hBitmap EndFunc ;==>DrawGridToBitmap1 point
-
#include <GDIPlus.au3> Global Const $iCellSize = 30 Global Const $iMaxRadius = 10 Global Const $iMinRadius = 5 ; Run some tests DrawGrid(10) DrawGrid(100) DrawGrid(250) DrawGrid(500) DrawGrid(1000) Func DrawGrid($iSize, $iCellBackgroundColor = 0xFFFFFFFF, $iCellBorderColor = 0xFF000000, $iCellBorderSize = 1, $iCircleColor = 0xFF800000) Local $iStartPeak = Round((ProcessGetStats())[1] / 1024 / 1024) Local $iTimer = TimerInit() Local $iRow, $iCol, $iDiameter, $iRadius, $iCalc Local $iCenter = Int($iCellSize / 2) Local $iImgSize = $iSize * $iCellSize _GDIPlus_Startup() Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iImgSize, $iImgSize) If @error Then ConsoleWrite('Grid size: ' & $iSize & ' - Error: _GDIPlus_BitmapCreateFromScan0' & @CRLF) _GDIPlus_Shutdown() Return EndIf Local $hCell = _GDIPlus_BitmapCreateFromScan0($iCellSize, $iCellSize) Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hCell) Local $hPen = _GDIPlus_PenCreate($iCellBorderColor, $iCellBorderSize) _GDIPlus_GraphicsClear($hGraphics, $iCellBackgroundColor) _GDIPlus_GraphicsDrawRect($hGraphics, 0, 0, $iCellSize - 1, $iCellSize - 1, $hPen) _GDIPlus_PenDispose($hPen) _GDIPlus_GraphicsDispose($hGraphics) Local $hTexture = _GDIPlus_TextureCreate($hCell) $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsFillRect($hGraphics, 0, 0, $iImgSize, $iImgSize, $hTexture) _GDIPlus_BrushDispose($hTexture) $hTexture = _GDIPlus_BrushCreateSolid($iCircleColor) ; Draw circles For $Index = 0 To $iSize * $iSize - 1 $iRow = Int($Index / $iSize) $iCol = Mod($Index, $iSize) $iRadius = Random($iMinRadius, $iMaxRadius, 1) $iDiameter = $iRadius * 2 $iCalc = $iCenter - $iRadius _GDIPlus_GraphicsFillEllipse($hGraphics, $iCol * $iCellSize + $iCalc, $iRow * $iCellSize + $iCalc, $iDiameter, $iDiameter, $hTexture) Next _GDIPlus_BrushDispose($hTexture) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_BitmapDispose($hCell) _GDIPlus_ImageSaveToFile($hBitmap, 'grid_' & $iSize & '.png') _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() Local $iDiff = TimerDiff($iTimer) Local $iEndPeak = Round((ProcessGetStats())[1] / 1024 / 1024) ConsoleWrite('Grid size: ' & $iSize & ' generated in ' & ($iDiff > 1000 ? Int($iDiff / 1000) & ' s' : Int($iDiff) & ' ms') & '. Memory peaks ' & $iStartPeak & " -> " & $iEndPeak & ' MB.' & @CRLF) EndFunc Results: Grid 10: 19.5998 ms Grid 100: 487.9959 ms Grid 250: 3 s Grid 500: 14 s Grid 1000: 43 s Last image it's not created probably due some limitations (a grid of 1000x1000 with 30 as cell size it's an image of 30000x30000 pixels) but I manage to produce an image with a cell size of 20 px. For grid I basically fill the entire image with a texture of a single cell (see @UEZ post) and for circles I use a single loop and some math (nested loops in AutoIt are really slow).1 point
-
MsgBox_Extn() UDF
SmOke_N reacted to argumentum for a topic
..and I asked myself, how will it run in another language ?, about Win 7 ?. So I installed Win7 in Spanish. Much easier than French or Korean for me. then am like I'll add this and that and, oh, let's show the errors to DClick in SciTE and jump to the function. Let's make it child proof. A teaching UDF. Well, is a patch after a patch. I thought of adding BttnEnableIndependently() and I said ( to my self ), stop. So I added ControlEnable($HWnd, .. to the example. I should have code it ... differently, but I hope it answers questions like -as I said above- how can I make the error jump to the file with the code other than the current script. Has the ReturnMeaning ( IDTIMEOUT ). I thought it'd be good. I hope it brings ideas to those that could use something like this. I know that I don't have use for it. Good old MsgBox is enough, ... and even that I ever use.0 points