wolflake Posted December 28, 2018 Share Posted December 28, 2018 I'm doing something wrong but I don't know why. I set up a function to put up a window. I call it to show it works and close it. Then I set the title of the hidden autoit window, get the handle and use that handle in setting up a timer for 2 seconds to call a function that kills the timer and calls the window again. The window starts to open then freezes and when you close it autoit is not responding. My goal was to have different timers that would call a function that would open different windows with different messages but can't even get one to work. The code below demonstrates the problem. Thanks in advance for any help. expandcollapse popup;timer test #include <timers.au3> __arlm("hi") AutoItWinSetTitle("rs") $hWnd = WinGetHandle("rs") ConsoleWrite($hWnd & @CRLF) $iWait = 2 * 1000 ;2 seconds $iIDTimer = _Timer_SetTimer($hWnd, $iWait, "alrm1") ; create timer $n = 0 While $n < 5 Sleep(1000) $n += 1 ConsoleWrite($n & @CRLF) WEnd Exit Func alrm1($hWnd, $iMsg, $iIDtimer, $iTime) #forceref $hWnd, $iMsg, $iIDtimer, $iTime _Timer_KillTimer($hWnd, $iIDtimer) $msg1 = "You have it now." ;ShellExecute(@ScriptDir & "\pp_msg.au3", $msg) __arlm("ho") EndFunc ;==>alrm1 Func __arlm($msg) #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Form1", 218, 104, 192, 124) $Edit1 = GUICtrlCreateEdit("", 16, 16, 185, 65, BitOR($ES_AUTOVSCROLL, $ES_AUTOHSCROLL, $ES_WANTRETURN)) GUICtrlSetData(-1, $msg) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE GUIDelete($Form1) Return EndSwitch WEnd EndFunc ;==>_arlm Link to comment Share on other sites More sharing options...
Tekk Posted December 28, 2018 Share Posted December 28, 2018 (edited) The problem is likely due to "_Timer_KillTimer" being called while inside the callback. Inside "_Timer_KillTimer" is a call to "DllCallbackFree" which is effectively freeing memory which is due to be executed when called inside the callback. I would recommend using "AdlibRegister" and "AdlibUnRegister" which are really just built in versions of the same thing. I've not tested it but at face value I do believe that it will solve your problem. Edit: As a side note you might reconsider your program flow. All callback type functions should be returned from as quickly as possible. Hanging in them, which your posted code does, can lead to unexpected issues. Edited December 28, 2018 by Tekk wolflake 1 Link to comment Share on other sites More sharing options...
wolflake Posted December 28, 2018 Author Share Posted December 28, 2018 (edited) @Tekk thanks for your help. I tried your first suggestion of taking the _Timer_KillTimer out of the callback (BTW the reason I put it there was to free up the timer asap ) Here is the code I used. Basically setting a flag to be used outside the callback. $iWait = 2 * 1000 ;2 seconds $iIDTimer = _Timer_SetTimer($hWnd, $iWait, "alrm1") ; create timer $n = 0 While $n < 5 Sleep(1000) $n += 1 ConsoleWrite($n & @CRLF) if $kill = True then _Timer_KillTimer($hWnd, $iIDtimer) EndIf WEnd Exit Func alrm1($hWnd, $iMsg, $iIDtimer, $iTime) #forceref $hWnd, $iMsg, $iIDtimer, $iTime $kill = True $msg1 = "You have it now." ;ShellExecute(@ScriptDir & "\pp_msg.au3", $msg) __arlm("ho") EndFunc ;==>alrm1 I suspect the issue may have something to do with using 2 windows (Autoit hidden, and the Form1) in the same script because if I call the message window as a separate script it works but then I have the issue of communicating between two running script (it's doable but not as easy). As you say AdlibRegister may be a better choice. I just had not used timers before and I wanted to understand why this is a problem. Also I take your thought about not hanging the callback so if I can get this to work I'll do it with a flag to run. I just tried the flag to run instead of running inside the callback and it worked! While $n < 5 Sleep(1000) $n += 1 ConsoleWrite($n & @CRLF) if $kill = True then __arlm("ho") $kill = False EndIf WEnd Exit Func alrm1($hWnd, $iMsg, $iIDtimer, $iTime) #forceref $hWnd, $iMsg, $iIDtimer, $iTime $kill = True _Timer_KillTimer($hWnd, $iIDtimer) EndFunc ;==>alrm1 @Tekk thanks again for putting me on the right track. Edited December 28, 2018 by wolflake Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now