Jump to content

Recommended Posts

Posted

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:
 

#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 ;==>Terminate

Now, 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:

#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
Posted (edited)

Hi,

use HotKeySet

look the FAQ

saludos

Edited by Danyfirex
Posted (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 by czardas
Posted (edited)

Same idea as above but a lot neater. The above code is an example of bad coding practice.

;

#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 by czardas
Posted

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.

;

#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.

Posted (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 by czardas
Posted

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:

#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.

Posted (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 by czardas
Posted (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.

;

#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 by czardas

Create an account or sign in to comment

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

Create an account

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

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...