Anne Posted September 17, 2013 Posted September 17, 2013 Hi scripters. I have been working on a little tool but then I ran into a problem. I have found a way to stop a loop/pause the script with the click of a button. However, the loop will continue until the end of the loop before stopping. This is the script which pauses after the loop has ended: expandcollapse popup#include <GUIConstantsEx.au3> #Region ### START Koda GUI section ### Form= Opt("GUIOnEventMode", 1) $doit = False $Form1 = GUICreate("Pause Toggle Project", 470, 65, 351, 254) $Button1 = GUICtrlCreateButton("START / PAUSE", 8, 16, 129, 33) $Button2 = GUICtrlCreateButton("EXIT PROGRNAM", 310, 16, 129, 33) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### GUICtrlSetOnEvent($Button1, "TogglePause") GUICtrlSetOnEvent($Button2, "Terminate") GUISetOnEvent($GUI_EVENT_CLOSE, "Close") GUISetState() While 1 Sleep(100) If $doit Then $i = 0 Do ConsoleWrite(123 & @CRLF) Sleep(1000) ConsoleWrite(456 & @CRLF) Sleep(1000) ConsoleWrite(789 & @CRLF) Sleep(1000) ConsoleWrite("abc" & @CRLF) Sleep(1000) ConsoleWrite("def" & @CRLF) Sleep(1000) ConsoleWrite("ghi" & @CRLF) Sleep(1000) Until $i = 100 Or $doit = False ToolTip('Stopping Loop...') Sleep(1500) $doit = False ToolTip('') EndIf WEnd Func TogglePause() $doit = Not $doit EndFunc Func Close() Exit EndFunc ;==>CancelPressed Func Terminate() Exit 0 EndFunc ;==>TerminateNow, I was wondering if it could be possible to stop the DO loop immediately. So that it breaks out of the loop when you click a button (call the function). I have tried a little with ExitLoop. However, I have hit an impassable wall. I added a new function called "Abort()". Calling this will break out of the DO loop and execute the code after UNTIL. However, this also breaks the script so that no buttons will work. I believe the GUICtrlSetOnEvent stops working. Is it possible to use the ExitLoop within the Abort() function without breaking my script? Or am I approaching this entirely wrong? The following code is the same as the above, but with the Abort() function: expandcollapse popup#include <GUIConstantsEx.au3> #Region ### START Koda GUI section ### Form= Opt("GUIOnEventMode", 1) $doit = False $Form1 = GUICreate("Pause Toggle Project", 470, 65, 351, 254) $Button1 = GUICtrlCreateButton("START / PAUSE", 8, 16, 129, 33) $Button2 = GUICtrlCreateButton("EXIT PROGRNAM", 310, 16, 129, 33) $Button3 = GUICtrlCreateButton("ABORT LOOP NOW", 160, 16, 129, 33) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### GUICtrlSetOnEvent($Button1, "TogglePause") GUICtrlSetOnEvent($Button2, "Terminate") GUICtrlSetOnEvent($Button3, "Abort") GUISetOnEvent($GUI_EVENT_CLOSE, "Close") GUISetState() While 1 Sleep(100) If $doit Then $i = 0 Do ConsoleWrite(123 & @CRLF) Sleep(1000) ConsoleWrite(456 & @CRLF) Sleep(1000) ConsoleWrite(789 & @CRLF) Sleep(1000) ConsoleWrite("abc" & @CRLF) Sleep(1000) ConsoleWrite("def" & @CRLF) Sleep(1000) ConsoleWrite("ghi" & @CRLF) Sleep(1000) Until $i = 100 Or $doit = False ToolTip('Stopping Loop...') Sleep(1500) $doit = False ToolTip('') EndIf WEnd Func TogglePause() $doit = Not $doit EndFunc Func Close() Exit EndFunc ;==>CancelPressed Func Terminate() Exit 0 EndFunc ;==>Terminate Func Abort() If $doit = False Then $doit = Not $doit ElseIf $doit = True Then $doit = Not $Doit While 1 ExitLoop 2 WEnd EndIf EndFunc
Danyfirex Posted September 17, 2013 Posted September 17, 2013 (edited) Hi, use HotKeySet look the FAQ saludos Edited September 17, 2013 by Danyfirex Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut
czardas Posted September 17, 2013 Posted September 17, 2013 (edited) There is a great tutorial about Interrupting a Running Function in the wiki: http://www.autoitscript.com/wiki/Interrupting_a_running_function Read through it and try to understand the code in the examples. I haven't looked at your code, but ExitLoop() will get you out of a loop. Edited September 17, 2013 by czardas operator64 ArrayWorkshop
czardas Posted September 17, 2013 Posted September 17, 2013 (edited) CODE DELETED (it was not a good example) ; Now the method shown may not be suitable depending on what your program is ultimately going to do. It is important to look at the examples I linked to earlier where the code is using well tested and standard methods. Next to try a different approach. Edited September 17, 2013 by czardas operator64 ArrayWorkshop
czardas Posted September 17, 2013 Posted September 17, 2013 (edited) Same idea as above but a lot neater. The above code is an example of bad coding practice. ; expandcollapse popup#include <GUIConstantsEx.au3> #Region ### START Koda GUI section ### Form= Opt("GUIOnEventMode", 1) $doit = False $Form1 = GUICreate("Pause Toggle Project", 470, 65, 351, 254) $Button1 = GUICtrlCreateButton("START / PAUSE", 8, 16, 129, 33) $Button2 = GUICtrlCreateButton("EXIT PROGRNAM", 310, 16, 129, 33) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### GUICtrlSetOnEvent($Button1, "TogglePause") GUICtrlSetOnEvent($Button2, "Close") ; Changed GUISetOnEvent($GUI_EVENT_CLOSE, "Close") GUISetState() Local $aData[6] = [123, 456, 789, "abc", "def", "ghi"] ; This array stores the text we want to send. Local $iCount1 = 0, $iCount2 = 0 While 1 Sleep(100) If $doit Then $iCount2 = 0 ; Reset or it will stop running. While 1 If $doit = False Or $iCount2 = 100 Then ExitLoop ConsoleWrite($aData[$iCount1] & @CRLF) Sleep(1000) $iCount1 = Mod($iCount1 + 1, 6) $iCount2 += 1 WEnd ToolTip('Stopping Loop...') Sleep(1500) $doit = False ToolTip('') EndIf WEnd Func TogglePause() $doit = Not $doit EndFunc Func Close() Exit EndFunc ;==>CancelPressed ; Ultimately you are going to have to get used to other methods. Edited September 17, 2013 by czardas operator64 ArrayWorkshop
Anne Posted September 17, 2013 Author Posted September 17, 2013 Hi, use HotKeySet look the FAQ saludos HotKeySet will do me no good because I need it to be a button which stops the loop. However, HotKeySet do stop the loop when the following function is called with a hotkey: Func MyExit() $doit = Not $Doit While 1 ExitLoop 2 WEnd EndFunc Any particular reason it works with HotKeySet and not when the function is called by other means? The method you are using is not ideal. Here is a modification to your first post which solves the problem but still using your method. This can be done better, but I am posting the example so hopefully you will get an idea why your original code is broken. ; expandcollapse popup#include <GUIConstantsEx.au3> #Region ### START Koda GUI section ### Form= Opt("GUIOnEventMode", 1) $doit = False $Form1 = GUICreate("Pause Toggle Project", 470, 65, 351, 254) $Button1 = GUICtrlCreateButton("START / PAUSE", 8, 16, 129, 33) $Button2 = GUICtrlCreateButton("EXIT PROGRNAM", 310, 16, 129, 33) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### GUICtrlSetOnEvent($Button1, "TogglePause") GUICtrlSetOnEvent($Button2, "Close") ; Changed GUISetOnEvent($GUI_EVENT_CLOSE, "Close") GUISetState() Local $aData[6] = [123, 456, 789, "abc", "def", "ghi"] ; This array stores the text we want to send. Local $iCount Local $i = 0 While 1 Sleep(100) If $doit Then $iCount = 0 While 1 For $i = $i To 5 If $i = -1 Then $i = 0 If $doit = False Or $iCount = 100 Then ExitLoop ; Test after every command ConsoleWrite($aData[$i] & @CRLF) $iCount += 1 ; Increment the count Sleep(1000) If $i = 5 Then $i = -1 ; This will become 0 again on the next loop Next ;ConsoleWrite(123 & @CRLF) ;Sleep(1000) ;ConsoleWrite(456 & @CRLF) ;Sleep(1000) ;ConsoleWrite(789 & @CRLF) ;Sleep(1000) ;ConsoleWrite("abc" & @CRLF) ;Sleep(1000) ;ConsoleWrite("def" & @CRLF) ;Sleep(1000) ;ConsoleWrite("ghi" & @CRLF) ;Sleep(1000) WEnd ToolTip('Stopping Loop...') Sleep(1500) $doit = False ToolTip('') EndIf WEnd Func TogglePause() $doit = Not $doit EndFunc Func Close() Exit EndFunc ;==>CancelPressed ;Func Terminate() ; Exit 0 ;EndFunc ;==>Terminate ; Now the method shown may not be suitable depending on what your program is ultimately going to do. It is important to look at the examples I linked to earlier where the code is using well tested and standard methods. Next to try a different approach. I see the logic in using Arrays. But it will only work for certain things. Consider if I wanted the loop to contain several MsgBox and other functions. However, I will try to look at the link you brought in the earlier post. And thank you both for replying.
czardas Posted September 17, 2013 Posted September 17, 2013 (edited) Arrays are not always suitable and there is no best answer for every situation. You have a count up to 100. That won't always be there. I assumed you wanted the pattern to pause and not reset again to the beginning. All of what you are looping through can be done in a function and perhaps interrupted using one of several different methods. I linked you the tutorial. Edited September 17, 2013 by czardas operator64 ArrayWorkshop
Anne Posted September 17, 2013 Author Posted September 17, 2013 Arrays are not always suitable and there is no best answer for every situation. You have a count up to 100. That won't always be there. I assumed you wanted the pattern to pause and not reset again to the beginning. All of what you are looping through can be done in a function and perhaps interrupted using one of several different methods. I linked you the tutorial. Yea I gave it a read while you replied. I must say, brilliant tutorial! It gave me at least two ideas but I think I'll go with the flag strategy. Something like this: expandcollapse popup#include <GUIConstantsEx.au3> #Region ### START Koda GUI section ### Form= Opt("GUIOnEventMode", 1) $doit = False $Form1 = GUICreate("Pause Toggle Project", 470, 65, 351, 254) $Button1 = GUICtrlCreateButton("START / PAUSE", 8, 16, 129, 33) $Button2 = GUICtrlCreateButton("EXIT PROGRNAM", 310, 16, 129, 33) $Button3 = GUICtrlCreateButton("ABORT LOOP NOW", 160, 16, 129, 33) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### GUICtrlSetOnEvent($Button1, "TogglePause") GUICtrlSetOnEvent($Button2, "Terminate") GUICtrlSetOnEvent($Button3, "Abort") GUISetOnEvent($GUI_EVENT_CLOSE, "Close") GUISetState() $Abort = False While 1 Sleep(100) If $doit Then $i = 0 Do ConsoleWrite(123 & @CRLF) Sleep(100) If $Abort = True Then $Abort = False ExitLoop EndIf ConsoleWrite(456 & @CRLF) Sleep(100) If $Abort = True Then $Abort = False ExitLoop EndIf ConsoleWrite(789 & @CRLF) Sleep(100) If $Abort = True Then $Abort = False ExitLoop EndIf ConsoleWrite("abc" & @CRLF) Sleep(100) If $Abort = True Then $Abort = False ExitLoop EndIf ConsoleWrite("def" & @CRLF) Sleep(100) If $Abort = True Then $Abort = False ExitLoop EndIf ConsoleWrite("ghi" & @CRLF) Sleep(100) Until $i = 100 Or $doit = False ToolTip('Stopping Loop...') Sleep(1500) $doit = False ToolTip('') EndIf WEnd Func TogglePause() $doit = Not $doit EndFunc Func Close() Exit EndFunc ;==>CancelPressed Func Terminate() Exit 0 EndFunc ;==>Terminate Func Abort() $Abort = True EndFunc I'll just have to place the flag at multiple occasions like in the example above. To be honest, I had considered this idea myself as a last resort. I just think it's a horrible or broken solution. But I suppose that's the price you pay for using a single threaded language. Thank you, I'll consider this case solved.
czardas Posted September 17, 2013 Posted September 17, 2013 (edited) I'm glad you read it, and sorry my code was a bit rushed before. It looked worse after I added a line because I overlooked a detaill. Anyway Melba23 is responsible for that tutorial which helped me a lot I must say. Now I just looked at your code. There's still some things wrong. $i will never be 100 because you don't increment it anywhere in the loop. You must add $i += 1 somewhere. Edited September 17, 2013 by czardas operator64 ArrayWorkshop
czardas Posted September 17, 2013 Posted September 17, 2013 (edited) Now you can interrupt your process, you can also encapsulate repeated actions inside a function. I created a function _WooHoo() for this, which replaces the duplicated code. ; expandcollapse popup#include <GUIConstantsEx.au3> #Region ### START Koda GUI section ### Form= Opt("GUIOnEventMode", 1) Global $doit = False Global $Form1 = GUICreate("Pause Toggle Project", 470, 65, 351, 254) Global $Button1 = GUICtrlCreateButton("START / PAUSE", 8, 16, 129, 33) Global $Button2 = GUICtrlCreateButton("EXIT PROGRNAM", 310, 16, 129, 33) Global $Button3 = GUICtrlCreateButton("ABORT LOOP NOW", 160, 16, 129, 33) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### GUICtrlSetOnEvent($Button1, "TogglePause") GUICtrlSetOnEvent($Button2, "Close") ; Changed again GUICtrlSetOnEvent($Button3, "Abort") GUISetOnEvent($GUI_EVENT_CLOSE, "Close") GUISetState() Global $Abort = False While 1 Sleep(100) If $doit Then $Abort = False $i = 0 ; This needs some work Do If _WooHoo(123) Then ExitLoop If _WooHoo(456) Then ExitLoop If _WooHoo(789) Then ExitLoop If _WooHoo("abc") Then ExitLoop If _WooHoo("def") Then ExitLoop If _WooHoo("ghi") Then ExitLoop $i += 1 Until $i = 100 Or $doit = False ToolTip('Stopping Loop...') Sleep(1500) $doit = False ToolTip('') EndIf WEnd Func _WooHoo($vInfo) ConsoleWrite($vInfo & @CRLF) Sleep(100) Return $Abort EndFunc Func TogglePause() $doit = Not $doit EndFunc Func Close() Exit EndFunc ;==>CancelPressed ;Func Terminate() ; Exit 0 ;EndFunc ;==>Terminate Func Abort() $Abort = True EndFunc ; or maybe something like this alternative. Func _WooHoo($vInfo) If $Abort Then Return True ConsoleWrite($vInfo & @CRLF) Sleep(100) EndFunc Edited September 17, 2013 by czardas operator64 ArrayWorkshop
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