Jump to content

How to use a stop button to end a loop


Recommended Posts

Hello, I have made this basic counter that will count seconds based off of the user input. While the counter is going, you cannot stop it or do anything until it is finished. How can I use the stop button to end the loop?

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

$Form2 = GUICreate("Counter", 193, 103, 302, 218)
$Input1 = GUICtrlCreateInput("", 8, 24, 41, 21)
$Label1 = GUICtrlCreateLabel("Seconds", 56, 26, 58, 20)
GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
$Button1 = GUICtrlCreateButton("Go", 8, 64, 75, 25)
$Button2 = GUICtrlCreateButton("Stop", 88, 64, 75, 25)
$Input2 = GUICtrlCreateInput("", 136, 24, 41, 21)
GUICtrlSetState($Input2, $GUI_DISABLE)
$Group1 = GUICtrlCreateGroup("Input", 0, 8, 121, 49)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$Group2 = GUICtrlCreateGroup("Output", 128, 8, 57, 49)
GUICtrlCreateGroup("", -99, -99, 1, 1)
GUISetState(@SW_SHOW)


While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button1
            $Read1 = GUICtrlRead($Input1)
            $sec = 0
            Do
                Sleep(1000)
                $sec = $sec + 1
                GUICtrlSetData($Input2, $sec)
            Until $sec = $Read1
    EndSwitch
WEnd
Link to comment
Share on other sites

When you want to keep a UI reactive it's best to avoid wait and sleep functions and leave the main loop as little as possible. Failing that, you can also call GUIGetMsg() outside the main loop to check if a button is pressed like this:

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

$Form2 = GUICreate("Counter", 193, 103, 302, 218)
$Input1 = GUICtrlCreateInput("", 8, 24, 41, 21)
$Label1 = GUICtrlCreateLabel("Seconds", 56, 26, 58, 20)
GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
$Button1 = GUICtrlCreateButton("Go", 8, 64, 75, 25)
$Button2 = GUICtrlCreateButton("Stop", 88, 64, 75, 25)
$Input2 = GUICtrlCreateInput("", 136, 24, 41, 21)
GUICtrlSetState($Input2, $GUI_DISABLE)
$Group1 = GUICtrlCreateGroup("Input", 0, 8, 121, 49)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$Group2 = GUICtrlCreateGroup("Output", 128, 8, 57, 49)
GUICtrlCreateGroup("", -99, -99, 1, 1)
GUISetState(@SW_SHOW)


While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button1
            $Read1 = GUICtrlRead($Input1)
            $iTimer = TimerInit()
            $iSec = -1
            $iSecLast = -1
            Do
                $iSec = Int(TimerDiff($iTimer)/1000)
                If $iSec <> $iSecLast Then
                    $iSecLast = $iSec
                    GUICtrlSetData($Input2,$iSec)
                EndIf
            Until $iSec = $Read1 Or GUIGetMsg() = $Button2
    EndSwitch
WEnd
Link to comment
Share on other sites

You can use e.g. Adlibregister() function to do this:

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

$Form2 = GUICreate("Counter", 193, 103, 302, 218)
$Input1 = GUICtrlCreateInput("", 8, 24, 41, 21)
$Label1 = GUICtrlCreateLabel("Seconds", 56, 26, 58, 20)
GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
$Button1 = GUICtrlCreateButton("Go", 8, 64, 75, 25)
$Button2 = GUICtrlCreateButton("Stop", 88, 64, 75, 25)
GUICtrlSetState($Button2, $GUI_Disable)
$Input2 = GUICtrlCreateInput("", 136, 24, 41, 21)
GUICtrlSetState($Input2, $GUI_DISABLE)
$Group1 = GUICtrlCreateGroup("Input", 0, 8, 121, 49)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$Group2 = GUICtrlCreateGroup("Output", 128, 8, 57, 49)
GUICtrlCreateGroup("", -99, -99, 1, 1)
GUISetState(@SW_SHOW)


While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button1
            GUICtrlSetState($Button1, $GUI_Disable)
            GUICtrlSetState($Button2, $GUI_Enable)
            $sec = 0
            AdlibRegister("Counter", 1000)
            GUICtrlSetState($Button1, $GUI_Disable)
        Case $Button2
            GUICtrlSetState($Button2, $GUI_Disable)
            GUICtrlSetState($Button1, $GUI_Enable)
            AdlibUnRegister("Counter")
    EndSwitch
WEnd

Func Counter()
    If $sec >= GUICtrlRead($Input1) - 1 Then
        GUICtrlSetState($Button2, $GUI_Disable)
        GUICtrlSetState($Button1, $GUI_Enable)
        AdlibUnRegister("Counter")
    EndIf
    $sec += 1
    GUICtrlSetData($Input2, $sec)
EndFunc

The problem is that you cannot check GUIGetMsg() value when you are in a loop!

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

The problem is that you cannot check GUIGetMsg() value when you are in a loop!

You could stick GUIGetMsg() in a adlib :graduated:

I don't think I've ever seen anyone do that btw. Adlibs are soo underused.

Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

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