Search the Community
Showing results for tags 'Callback'.
-
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.
-
Function Reference _AdlibEnhance.au3 Adlib function with support for parameters, pause and resume using Call Back! Sintax: _Adlib_Register( "Function" [, "Params" [, Time [, RepeatCount ]]] ) _Adlib_Pause( "Function" ) _Adlib_Resume( "Function" ) _Adlib_SetTimer( "Function" [, Time ] ) _Adlib_UnRegister( "Function" ) Supports: ; You can call functions with parameters and native functions also! Downloads: Version: 0.10 _AdlibEnhance_(RedirectLink).html Note: Usage example is included! Sample: Fixes: Regards, João Carlos.
- 22 replies
-
- adlib
- adlibregister
-
(and 3 more)
Tagged with:
-
Hey everyone, I searched some hours for a way to use the function WaitForSingleObject not as a function the script has to wait for, but a function which calls a callback function when the event is signaled. I found a way with RegisterWaitForSingleObject but no AutoIt implemention, so I made one on my own, and now I want to share it with you guys! The only limitation by this implemention is that you are not able to use more than one callback at once. to avoid this, you could write a static array in the function which fills with the selfmade callback structs. If you find another way, let me know! Example: Hope you like it and find use for it! Greetz, Spider RegisterWaitForSingleObject.zip
-
Hello all, Back again it seems. I've hit a snag in the below script. I use this on win 7 and XP machines frequently and have just realized that sorting using column headers is not 'working' (is not updating listview; it looks like something is going on behind the scenes..) when clicked. Also this does not show the sorting arrow when using the callback sort functionality. So, to sum up, I am not seeing the arrow keys when clicking the column header to sort. And, it is not sorting the values in the $List1 ListView box on a win XP machine. #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <EditConstants.au3> #include <Constants.au3> #include <GUIListBox.au3> #include <GUIEdit.au3> #include <GuiListView.au3> #include <Array.au3> #include <ButtonConstants.au3> #include <ScrollBarConstants.au3> #include <GuiScrollBars.au3> Local $List1, $List2, $List3, $List4, $GUIhandle Local $Button19, $Button91, $ButtonAZ, $ButtonZA Local $hChild_1, $cLabel_1, $cLabel_2, $cLabel_3 GUI() Repaint() Local $bSysMsg = False Local $aRect = _GUICtrlListView_GetItemRect($List1, 0) $iDeltaY = $aRect[3] - $aRect[1] _GUIScrollBars_EnableScrollBar(ControlGetHandle("", "", $List2), $SB_BOTH, $ESB_DISABLE_BOTH) _GUIScrollBars_EnableScrollBar(ControlGetHandle("", "", $List3), $SB_BOTH, $ESB_DISABLE_BOTH) _GUICtrlListView_RegisterSortCallBack($List1) _GUICtrlListView_RegisterSortCallBack($List2) _GUICtrlListView_RegisterSortCallBack($List3) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUIRegisterMsg($WM_SIZE, "WM_SIZE") GUIRegisterMsg($WM_SYSCOMMAND, "_WM_SYSCOMMAND") While 1 $msg = GUIGetMsg(1) Switch $msg[1] Case $GUIhandle Switch $msg[0] Case $GUI_EVENT_CLOSE Quit() EndSwitch If $bSysMsg Then $bSysMsg = False _Resize_ListViews() EndIf Case $hChild_1 Switch $msg[0] Case $GUI_EVENT_CLOSE GUIDelete($hChild_1) EndSwitch EndSwitch WEnd Func Repaint() Local $L1, $L2, $L3 _GUICtrlListView_BeginUpdate($List1) _GUICtrlListView_DeleteAllItems($List1) _GUICtrlListView_BeginUpdate($List2) _GUICtrlListView_DeleteAllItems($List2) _GUICtrlListView_BeginUpdate($List3) _GUICtrlListView_DeleteAllItems($List3) For $Index = 0 To 10 Step 1 $L1 = _GUICtrlListView_AddItem($List1, $Index, $Index) $L2 = _GUICtrlListView_AddItem($List2, $Index, $Index) $L3 = _GUICtrlListView_AddItem($List3, $Index, $Index) Next _GUICtrlListView_SetColumnWidth($List1, 0, $LVSCW_AUTOSIZE) _GUICtrlListView_SetColumnWidth($List2, 0, $LVSCW_AUTOSIZE) _GUICtrlListView_EndUpdate($List1) _GUICtrlListView_EndUpdate($List2) _GUICtrlListView_EndUpdate($List3) EndFunc ;==>Repaint Func Quit() _GUICtrlListView_UnRegisterSortCallBack($List1) _GUICtrlListView_UnRegisterSortCallBack($List2) _GUICtrlListView_UnRegisterSortCallBack($List3) Exit EndFunc ;==>Quit Func GUI() Local $Index, $LV1, $LV2, $LV3, $L1_EX, $L2_EX, $L3_EX $GUIhandle = GUICreate("ArchServer", 680, 575, -1, -1, $WS_SIZEBOX + $WS_SYSMENU + $WS_MAXIMIZEBOX + $WS_MINIMIZEBOX) ;creates the parent window $List1 = _GUICtrlListView_Create($GUIhandle, "Computer Name ", 20, 35, 300, 448, -1, $LVS_EX_DOUBLEBUFFER) ;;$ES_READONLY incase you don't want to be able to select text $cLabel_1 = GUICtrlCreateLabel("", 20, 35, 300, 448) GUICtrlSetState($cLabel_1, $GUI_DISABLE) GUICtrlSetResizing($cLabel_1, $GUI_DOCKAUTO) GUICtrlSetBkColor($cLabel_1, $GUI_BKCOLOR_TRANSPARENT) _GUICtrlListView_SetExtendedListViewStyle($List1, $LVS_EX_TWOCLICKACTIVATE) $List2 = _GUICtrlListView_Create($GUIhandle, "Date/Time", 355, 35, 190, 450, -1, BitOR($LVS_EX_DOUBLEBUFFER, $LVS_EX_FLATSB)) $cLabel_2 = GUICtrlCreateLabel("", 355, 35, 190, 450) GUICtrlSetState($cLabel_2, $GUI_DISABLE) GUICtrlSetResizing($cLabel_2, $GUI_DOCKAUTO) GUICtrlSetBkColor($cLabel_2, $GUI_BKCOLOR_TRANSPARENT) $List3 = _GUICtrlListView_Create($GUIhandle, "Speed", 574, 35, 95, 450, -1, BitOR($LVS_EX_DOUBLEBUFFER, $LVS_EX_FLATSB)) $cLabel_3 = GUICtrlCreateLabel("", 574, 35, 95, 450) GUICtrlSetState($cLabel_3, $GUI_DISABLE) GUICtrlSetResizing($cLabel_3, $GUI_DOCKAUTO) GUICtrlSetBkColor($cLabel_3, $GUI_BKCOLOR_TRANSPARENT) GUICtrlCreateLabel("Additional Info", 20, 489) ;creates the label for $List4 GUICtrlSetResizing(-1, $GUI_DOCKSIZE) $List4 = GUICtrlCreateList("", 20, 512, 635, 40, BitOR($WS_BORDER, $WS_VSCROLL), $ES_READONLY) GUICtrlSetResizing($List4, $GUI_DOCKAUTO) GUICtrlCreateLabel("Active Connections: ", 525, 487) ;creates the label for the active connections GUICtrlSetResizing(-1, $GUI_DOCKSIZE) $ActiveConnections = GUICtrlCreateList("0", 625, 486, 30, 30) ;dynamically updating list of connections as they come in GUICtrlSetResizing($ActiveConnections, $GUI_DOCKSIZE) GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUISetState(@SW_SHOW) ;shows the GUI window For $Index = 0 To 10 Step 1 $LV1 = _GUICtrlListView_AddItem($List1, " ") ;adds a default value into $List1 $LV2 = _GUICtrlListView_AddItem($List2, " ") ;adds a default value into $List2 $LV3 = _GUICtrlListView_AddItem($List3, " ") ;adds a default value into $List3 Next EndFunc ;==>GUI Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, _ $ceLines, $cl $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Local Const $iLines = _SendMessage($List1, $LVM_GETTOPINDEX) - _SendMessage($List2, $LVM_GETTOPINDEX) _SendMessage($List2, $LVM_SCROLL, 0, $iLines * $iDeltaY) _SendMessage($List3, $LVM_SCROLL, 0, $iLines * $iDeltaY) Switch $hWndFrom Case $List1 Switch $iCode Case $LVN_COLUMNCLICK _GUICtrlListView_SortItems($List1, GUICtrlGetState($List1)) Case $NM_CLICK $sData = _GUICtrlListView_GetSelectedIndices($List1) _GUICtrlListView_SetItemSelected($List2, $sData, True, False) _GUICtrlListView_SetItemSelected($List3, $sData, True, False) EndSwitch Case $List2 Switch $iCode Case $LVN_COLUMNCLICK _GUICtrlListView_SortItems($List1, GUICtrlGetState($List1)) Case $NM_CLICK $sData = _GUICtrlListView_GetSelectedIndices($List2) _GUICtrlListView_SetItemSelected($List1, $sData, True, False) _GUICtrlListView_SetItemSelected($List3, $sData, True, False) EndSwitch Case $List3 Switch $iCode Case $LVN_COLUMNCLICK _GUICtrlListView_SortItems($List1, GUICtrlGetState($List1)) Case $NM_CLICK $sData = _GUICtrlListView_GetSelectedIndices($List3) _GUICtrlListView_SetItemSelected($List1, $sData, True, False) _GUICtrlListView_SetItemSelected($List2, $sData, True, False) EndSwitch EndSwitch EndFunc ;==>WM_NOTIFY Func WM_SIZE($hWnd, $msg, $wParam, $lParam) _Resize_ListViews() Return $GUI_RUNDEFMSG EndFunc ;==>WM_SIZE Func _WM_SYSCOMMAND($hWnd, $msg, $wParam, $lParam) Const $SC_MAXIMIZE = 0xF030 Const $SC_RESTORE = 0xF120 Switch $wParam Case $SC_MAXIMIZE, $SC_RESTORE $bSysMsg = True EndSwitch EndFunc ;==>_WM_SYSCOMMAND Func _Resize_ListViews() $aRet = ControlGetPos($GUIhandle, "", $cLabel_1) WinMove($List1, "", $aRet[0], $aRet[1], $aRet[2], $aRet[3]) $aRet = ControlGetPos($GUIhandle, "", $cLabel_2) WinMove($List2, "", $aRet[0], $aRet[1], $aRet[2], $aRet[3]) $aRet = ControlGetPos($GUIhandle, "", $cLabel_3) WinMove($List3, "", $aRet[0], $aRet[1], $aRet[2], $aRet[3]) EndFunc ;==>_Resize_ListViews ;========RESIZE FUNCTIONALITY THANKS TO MELBA All replies are much appreciated!
-
Hey folks, I just explored the new helpfile and found a new Keyword (dunno if its that new, but i never saw it before) called Volatile. It was made especally for CallBack and Com event functions, so I wanted to try that out. the advantage of this Keyword is, that you can run the Dll while you can do other things in autoit (AutoIt wont freeze/pause anymore while the dllcall is executed!) I made up a little example i want to share with you, the c source is compiled in MinGW, you need at least AutoIt 3.3.10.2. Hope you like it, would be interested in some comments Greetz, Spider testLibCallback.zip
-
Hi, I follow my project about the use of DirectInput with Autoit If i can create the interface correctly with the DirectInput8create Function I have a problem when i want to use Callback function to enum Devices. ("bad callee") i have Written this piece of code, but is it the the good syntax to callback the function _EnumJoystickProc? i have looked in this forum and Google, but no samples of code using callback and Objet, may be its no possible? Or there is a special syntax to callback function with autoit objet? Local $oDirectInput8 = ObjCreateInterface ( $sCLSID_DirectInput8 , $sIID_IDirectInput8 ,$dtagIDirectInput8 ) ; Create callback function Global $handle = DllCallbackRegister("_EnumJoystickProc", "BOOL", "ptr;ptr") $aa=$oDirectInput8.EnumDevices($DI8DEVCLASS_ALL,DllCallbackGetPtr($handle), 0, $DIEDFL_ATTACHEDONLY) ; MsgBox(0,hex($aa,8),$oDirectInput8) DllCallbackFree($handle) Exit Func _EnumJoystickProc($pDIinstance, $pContexte) MsgBox(0,"errrr","") Return $DIENUM_STOP EndFunc Regards Terry
-
I wanted to see if I could manage to use IAppVisibility (Win8) in one of my scripts. (it seems the name was changed in Release Preview but MSDN wasn't updated) It took some time but I learned to make tlb file and made definitions for GetAppVisibilityOnMonitor and IsLauncherVisible methods (working good as far as I can tell), but I would like Advise and Unadvise too if possible, but I don't know how... See definition on above link. Only example I found is some (too advanced for me to translate) c++ code. Here. But it compiles and runs fine at least. trancexx is doing a similar thing in maybe that can be used somehow? Anyone have a clue? Test script with the working funcs: #include <WinAPI.au3> ;=============================================================================== #interface "IAppVisibility" Global Const $sCLSID_AppVisibility = "{7E5FE3D9-985F-4908-91F9-EE19F9FD1514}" Global Const $sIID_IAppVisibility = "{2246EA2D-CAEA-4444-A3C4-6DE827E44313}" ; Definition Global Const $tagIAppVisibility = "GetAppVisibilityOnMonitor hresult(ptr;int*);" & _ "IsLauncherVisible hresult(int*);" & _ "Advise hresult(ptr;dword*);" & _ "Unadvise hresult(dword);" ;============================================================================== Local $oAppVisibility = ObjCreateInterface($sCLSID_AppVisibility, $sIID_IAppVisibility, $tagIAppVisibility) ;~ MsgBox(0, @ScriptName, IsObj($oAppVisibility)) ;~ ConsoleWrite(IsObj($oAppVisibility) & @CRLF) If Not IsObj($oAppVisibility) Then ConsoleWrite("NOT IsObj" & @LF) MsgBox(0, "", "NOT IsObj") Exit EndIf HotKeySet("ö", "_IsLauncherVisible") HotKeySet("å", "_GetAppVisibilityOnMonitor") $oMyError = ObjEvent("AutoIt.Error", "ErrFunc") ; Install a custom error handler $callback=DllCallbackRegister("_MonitorEnumProc","int","ptr;ptr;ptr;lparam") Global $Monitor DllCall("user32.dll","int","EnumDisplayMonitors","ptr",0,"ptr",0,"ptr",DllCallbackGetPtr($callback),"lparam",10) While 1 Sleep(1000) WEnd Func _IsLauncherVisible() Local $bVisible $iRet = $oAppVisibility.IsLauncherVisible($bVisible) ;~ If @error Then ;Enable this and disable AutoIt.Error if on Alpha ;~ MsgBox(0, @ScriptName, @error) ;~ EndIf ToolTip("1: " & $iRet & @CRLF & "2: " & $bVisible) EndFunc Func _GetAppVisibilityOnMonitor() Local $iMode $iRet = $oAppVisibility.GetAppVisibilityOnMonitor($Monitor, $iMode) ToolTip("1: " & $iRet & @CRLF & "2: " & $iMode) EndFunc ; This is a custom error handler Func ErrFunc() $HexNumber = Hex($oMyError.number, 8) MsgBox(0, "", "We intercepted a COM Error !" & @CRLF & _ "Number is: " & $HexNumber & @CRLF & _ "WinDescription is: " & $oMyError.windescription) $iEventError = 1 ; Use to check when a COM Error occurs EndFunc ;==>ErrFunc Func _MonitorEnumProc($hMonitor, $hdcMonitor, $lprect, $lparam) MsgBox(0, "Monitor", "Monitor handle: " & $hMonitor & @CRLF & "LPARAM: " & $lparam) $Monitor = $hMonitor EndFunc Here's tlb stuff: ================================================================================== coclass AppVisibility; CLSID = {7E5FE3D9-985F-4908-91F9-EE19F9FD1514}; // Implemented interface: <Interface> IAppVisibility ================================================================================== Interface IAppVisibility; IID = {2246EA2D-CAEA-4444-A3C4-6DE827E44313}; // Inherits from: IUnknown {00000000-0000-0000-C000-000000000046} 1. STDCALL FUNC PUREVIRTUAL; HRESULT GetAppVisibilityOnMonitor( [in] hMonitor, [out] int* pMode ); 2. STDCALL FUNC PUREVIRTUAL; HRESULT IsLauncherVisible( [out] int* pfVisible ); 3. STDCALL FUNC PUREVIRTUAL; HRESULT Advise( [in] * pCallback, [out] dword* pdwCookie ); 4. STDCALL FUNC PUREVIRTUAL; HRESULT Unadvise( [in] dword dwCookie ); ================================================================================== enum MONITOR_APP_VISIBILITY; { MAV_UNKNOWN = 0, MAV_NO_APP_VISIBLE = 1, MAV_APP_VISIBLE = 2 }; ================================================================================== Interface IAppVisibilityEvents; IID = {6584CE6B-7D82-49C2-89C9-C6BC02BA8C38}; // Inherits from: IUnknown {00000000-0000-0000-C000-000000000046} 1. STDCALL FUNC PUREVIRTUAL; HRESULT AppVisibilityOnMonitorChanged( [in] hMonitor, [in] previousMode, [in] currentMode ); 2. STDCALL FUNC PUREVIRTUAL; HRESULT LauncherVisibilityChange( [in] int currentVisibleState ); ==================================================================================
-
I know there's already several of these types of functions around the forum but there were some things I wanted to do different, so I wrote my own. In the tests I've done this appears to be working fine, but I'd appreciate a second look. The error returns and the first three parameters are the same as the vanilla _FileListToArray, but there are a couple new flags, and two new parameters. The new flags include: - enabling recursion (4) - disabling file count in element [0] (8) - enabling full path returns (16). The new parameters are: - $sCallback - this is the name of a function you want to run on each loop, it is passed an array with data relating to the current file search in the loop. If the callback function returns 0 then the item is processed normally. If it returns 1 the item is skipped (this can be used to skip entire folders being processed). If it returns -1 the entire function errors out with -1 and @extended is set to the callback function's @extended value. - $sCallbackUserParam - just an extra parameter that can be passed through to the callback function. Example with callback: #include <Array.au3> #include <_FileListToArrayRecursive.au3> Global $sWFile _FileListToArrayRecursive(@DesktopDir, '*', 4, '_Callback', 'Wfile') If @error = -1 And @extended = 42 Then MsgBox(0, '', 'You have a W file:' & @LF & $sWFile) Else MsgBox(0, '', 'No files/folders that start with W exist.') EndIf Global $aReadOnly = _FileListToArrayRecursive(@DesktopDir, '*', 1+4, '_Callback', 'readonly') Global $aEmpty = _FileListToArrayRecursive(@DesktopDir, '*', 1+4, '_Callback', 'empty') _ArrayDisplay($aReadOnly) _ArrayDisplay($aEmpty) Func _Callback($aParams) Switch $aParams[5] Case 'Wfile' If StringLeft($aParams[2], 1) == 'W' Then $sWFile = $aParams[1] & $aParams[2] Return SetExtended(42, -1) EndIf Case 'empty' If Not $aParams[3] Then If FileGetSize($aParams[0] & $aParams[1] & $aParams[2]) Then Return 1 EndIf Case 'readonly' If Not $aParams[3] Then If Not StringInStr(FileGetAttrib($aParams[0] & $aParams[1] & $aParams[2]), 'R') Then Return 1 EndIf EndSwitch EndFunc #include-once ; #FUNCTION# ==================================================================================================================== ; Name...........: _FileListToArrayRecursive ; Description ...: Lists files and/or folders in a specified path recursively ; Syntax.........: _FileListToArrayRecursive($sPath[, $sFilter = '*'[, $iFlag = 0[, $sCallback = ''[, $sCallbackUserParam = '' ] ] ] ] ) ; Parameters ....: $sPath - Path to search ; $sFilter - Optional: the filter to use, default is * ; $iFlag - Optional: specifies options about return, add flags together ; |$iFlag = 0 (Default) Return both files and folders ; |$iFlag = 1 Return files only ; |$iFlag = 2 Return folders only ; |$iFlag = 4 Search subfolders (Enable recursion) ; |$iFlag = 8 Make array 0-based (Disable return count in first element) ; |$iFlag = 16 Return full paths (default only returns from the search folder down) ; $sCallback - Optional: function to call on each loop. See remarks for details (default: none) ; $sCallbackUserParam - Optional: a parameter to pass to the Callback function (default: none) ; Return values .: @Error - 1 = Path not found or invalid ; |2 = Invalid $sFilter ; |3 = Invalid $iFilter ; |4 = No files found or folder inaccessible ; |5 = No files found or folder inaccessible ; |-1 = Callback function returned -1 ; Author ........: Rob Saunders (therks at therks dot com) ; Modified.......: ; Remarks .......: If $sCallback is defined the function will be called on each loop and it can alter what files are recorded ; in the return array. The Callback function runs on every file result because it is called *before* the flag ; filter for files/folders ($iFlag 1 or 2). ; Return 0 = Item is added (depending on $iFlag 1 or 2) ; Return 1 = Item is skipped (note: if you skip a folder it will not be searched either) ; Return -1 = Stop searching. Main func returns false, @error = -1, @extended = Callback's @extended value ; The function is passed one parameter, a 6 item array with values as follows: ; [0] root search folder ; [1] current sub folder ; [2] current filename match ; [3] 1 if file is a folder; 0 if not ; [4] current file count ; [5] $sCallbackUserParam ; ; Related .......: _FileListToArray ; Link ..........: ; Example .......: ; Note ..........: Some parts from original function (by SolidSnake) and _FileListToArrayEx (by DXRW4E) ; =============================================================================================================================== Func _FileListToArrayRecursive($sPath, $sFilter = '*', $iFlag = 0, $sCallback = '', $sCallbackUserParam = '') Local Const $FL_FILES = 1, $FL_FOLDERS = 2, $FL_RECURSE = 4, $FL_NOCOUNT = 8, $FL_FULLPATH = 16 If Not StringInStr(FileGetAttrib($sPath), 'D') Then Return SetError(1, 1, '') If StringRegExp($sFilter, '[\\/:><\|]|(?s)\A\s*\z') Then Return SetError(2, 2, '') If $iFlag < 0 Or $iFlag > 1+2+4+8+16 Then Return SetError(3, 3, '') $sPath = StringRegExpReplace($sPath, '[\\/]+$', '') & '\' Local $sFileTrack, $iFileCount, $hParentSearch, $hSearch, $hSubCheck, $sSubDir, $sFile, $iIsFolder, $sRegExFilter, $sAddFullPath, _ $iReturnFolders, $iReturnFiles, $iRecurse, $iReturnCount, $iSortOffset, _ $aCallbackData[6], $vCallbackReturn, $iCallbackExt $aCallbackData[5] = $sCallbackUserParam If BitAND($iFlag, $FL_FULLPATH) Then $sAddFullPath = $sPath If BitAND($iFlag, $FL_RECURSE) Then $iRecurse = 1 If StringReplace($sFilter, '*', '') Then ; If we ARE recursing, and the filter is something besides just * then initialize the regex filter $sRegExFilter = '(?i)^' & StringRegExpReplace(StringReplace(StringRegExpReplace($sFilter, '(\.|\||\+|\(|\)|\{|\}|\[|\]|\^|\$|\\)', "\\$1"), '?', '.'), '\*+', '.*') & '$' $sFilter = '*' EndIf EndIf If BitAND($iFlag, $FL_FILES) Then $iReturnFiles = 1 ElseIf BitAND($iFlag, $FL_FOLDERS) Then $iReturnFolders = 1 Else $iReturnFiles = 1 $iReturnFolders = 1 EndIf If BitAND($iFlag, $FL_NOCOUNT) Then $iReturnCount = 2 ; Param for StringSplit $iSortOffset = 0 EndIf $hParentSearch = FileFindFirstFile($sPath & $sSubDir & $sFilter) If $hParentSearch = -1 Then Return SetError(4, 4, '') $hSearch = $hParentSearch While 1 $sFile = FileFindNextFile($hSearch) If @error Then If $hParentSearch = $hSearch Then ExitLoop FileClose($hSearch) $hSearch -= 1 $sSubDir = StringLeft($sSubDir, StringInStr(StringTrimRight($sSubDir, 1), '\', 0, -1)) ContinueLoop EndIf $iIsFolder = @extended If $sCallback Then $aCallbackData[0] = $sPath $aCallbackData[1] = $sSubDir $aCallbackData[2] = $sFile $aCallbackData[3] = $iIsFolder $aCallbackData[4] = $iFileCount $vCallbackReturn = Call($sCallback, $aCallbackData) If @error = 0xDEAD And @extended = 0xBEEF Then FileClose($hSearch) FileClose($hParentSearch) Return SetError(5, 5, '') ElseIf $vCallbackReturn = -1 Then $iCallbackExt = @extended FileClose($hSearch) FileClose($hParentSearch) Return SetError(-1, $iCallbackExt, '') ElseIf $vCallbackReturn Then ContinueLoop EndIf EndIf If $iRecurse Then If ($iIsFolder And $iReturnFolders) Or (Not $iIsFolder And $iReturnFiles) Then If Not $sRegExFilter Or ($sRegExFilter And StringRegExp($sFile, $sRegExFilter)) Then $sFileTrack &= '|' & $sAddFullPath & $sSubDir & $sFile $iFileCount += 1 EndIf EndIf If $iIsFolder Then $hSubCheck = FileFindFirstFile($sPath & $sSubDir & $sFile & '\' & $sFilter) If $hSubCheck = -1 Then ContinueLoop $sSubDir &= $sFile & '\' $hSearch = $hSubCheck EndIf Else If ($iIsFolder And $iReturnFolders) Or (Not $iIsFolder And $iReturnFiles) Then $sFileTrack &= '|' & $sAddFullPath & $sSubDir & $sFile $iFileCount += 1 EndIf EndIf WEnd FileClose($hParentSearch) Local $aReturnList = StringSplit(StringTrimLeft($sFileTrack, 1), '|', $iReturnCount) If @error Then Return SetError(4, 4, '') Return $aReturnList EndFunc I'm still working on this as time goes by so the most up to date version can be found in my dropbox: http://db.tt/OqNgumLK
- 1 reply
-
- _FileListToArray
- Recursive
-
(and 2 more)
Tagged with: