Sign in to follow this  
Followers 0
Nei

Button stop don't work when function is active

10 posts in this topic

Hello,

I'm beginner with Autoit script...

i have made a gui complete with a lot of controls, and everything is fine.

So, I have made 3 buttons:

Start, Pause, Stop.

when start is pressed, this execute a function, and when this functions is active, pause or stop don't work via button, but by hotkey work.

Any example of this function here?

I've search a lot before start this thread, but is not easy for beginner's.

Thanks in advance.

Share this post


Link to post
Share on other sites



Nei,

Welcome to the AutoIt forum. :)

It would help if you posted the code you are having trouble with - but I can make a good guess at what is happening. :(

I imagine you are usung a GUIGetMsg loop to detect your key presses. When you press the start button, you leave that loop and enter your function. At this point you are no longer looking for the messages sent by the other keys as you are no longer going round the loop. That is why they become inactive - the HotKeys interrupt functions so they still work.

What can you do about it? Either poll GUIGetMsg within your function or just accept that you must use the HotKeys.

I hope this explains the problem. If not, post your code and we will take a closer look. :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Or if you're using onevent mode... another onevent function can not be triggered while another onevent function is still processing. In such cases I use guiregistermsg() to capture the button click and set a global loop breaking variable to true...

Share this post


Link to post
Share on other sites

OMG exactly!!!

@Melba23,

You've write exaclty my situation.

So, Who can I make it?

"Either poll GUIGetMsg within your function or just accept that you must use the HotKeys."

I understand wich it solve my problem, but i don't know the way to do.

@Kafu

Read your message, i think this method is easy to implement... but I'll have the same result as Melba23 method?

What's better?

Thanks for your support.

Share this post


Link to post
Share on other sites

Nei,

You've write exaclty my situation...but i don't know the way to do

Post your code as I suggested and we will look at what we can do. :(

M23

P.S. When you post code please use Code tags. Put [autoit ] before and [/autoit ] after your posted code (but omit the trailing space - it is only there so the tags display here). Or press the blue button just under the BOLD toolbar button.


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

@Kafu

Read your message, i think this method is easy to implement... but I'll have the same result as Melba23 method?

No, you won't.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Nei,

Post your code as I suggested and we will look at what we can do. :(

M23

P.S. When you post code please use Code tags. Put [autoit ] before and [/autoit ] after your posted code (but omit the trailing space - it is only there so the tags display here). Or press the blue button just under the BOLD toolbar button.

OK.

Current is:

# gui code

$btnCuidar = GUICtrlCreateButton("Cuidar", 4, 448, 192, 25, $WS_GROUP)

...

# variable definitions

Global $appAtivo = False

...

# functions

...

I've tried to add to this function your suggest:

So this work, but only in this function that have inside other main function wich i want to stop.

The code is big to paste all here, so the child function is:

Note: I want to do this function only one time for call.

Func _Cuidar() ; Routine to make some thinks when button is pressed.
    $appAtivo = Not $appAtivo
    While $appAtivo
        _AlinhaMouse()
        If $appAtivo Then
            If GUICtrlRead($chkColher) == $GUI_CHECKED  Then
                _Ferr7()
                _Clica("0",GUICtrlRead($cmbLotes),0)
            EndIf
        Else
            ExitLoop
        EndIf
        If $appAtivo Then
            If GUICtrlRead($chkRegar) == $GUI_CHECKED   Then
                _Ferr4()
                _Clica("0",GUICtrlRead($cmbLotes),0)
            EndIf
        Else
            ExitLoop
        EndIf
        If $appAtivo Then
            If GUICtrlRead($chkRemPP) == $GUI_CHECKED   Then
                _Ferr5()
                _Clica("0",GUICtrlRead($cmbLotes),0)
                _Ferr6()
                _Clica("0",GUICtrlRead($cmbLotes),0)
            EndIf
        Else
            ExitLoop
        EndIf
        If $appAtivo Then
            If GUICtrlRead($chkAtualizar) == $GUI_CHECKED   Then
                _FerrAtualizar()
            EndIf
        Else
            ExitLoop
        EndIf
        $appAtivo = Not $appAtivo
    WEnd
EndFunc

Func _appAtivo() ; exit loop of function active, I mean Stop.
    $appAtivo = Not $appAtivo
EndFunc

# hotkeys

HotKeySet("{ESC}", "_appAtivo") ; if pressed when the first IF is runing, the function _Cuidar stop, another way the loop will continue till end (need to stop when ESC is pressed from anytime)

# loop

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            _Sair()
        Case $btnCuidar
            _Cuidar()
...

PS: I read all code now, and maybe I need to explain code of "_Clica" also, is another loop like this _Cuidar...

So, i have to add this verification "$appAtivo" on every function that uses loop?

I have another problem. I have to execute one function every 5 minutes, and I do make sleep to do this, but none function respond when this sleep is running :)

So, is easy to make the Task to execute by time left?

Thanksss.

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Nei,

Here is a modified version of your script to show how to implement what I suggested above: :)

#include <GUIConstantsEx.au3>

HotKeySet("{ESC}", "_appAtivo")

$appAtivo = 0

$hGUI = GUICreate("Test", 500, 500)

$btnCuidar = GUICtrlCreateButton("Cuidar", 10, 10, 80, 30)
$btnStop = GUICtrlCreateButton("Stop", 10, 50, 80, 30)

$hlabel = GUICtrlCreateLabel("", 10, 100, 200, 20)

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            _Sair()
        Case $btnCuidar
            _Cuidar()
        Case $btnStop
            _appAtivo()

    EndSwitch

WEnd

Func _Sair()
    Exit
EndFunc   ;==>_Sair

Func _Cuidar() ; Routine to make some thinks when button is pressed.

    ; Set flag to show we are running
    $appAtivo = 1
    ; Keep running until $appAtivo is set to 0
    While $appAtivo

        Sleep(10) ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        GUICtrlSetData($hLabel, "Running") ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

        #cs ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        _AlinhaMouse()
        If GUICtrlRead($chkColher) = $GUI_CHECKED Then
            _Ferr7()
            _Clica("0", GUICtrlRead($cmbLotes), 0)
        EndIf

        If GUICtrlRead($chkRegar) = $GUI_CHECKED Then
            _Ferr4()
            _Clica("0", GUICtrlRead($cmbLotes), 0)
        EndIf
        If GUICtrlRead($chkRemPP) = $GUI_CHECKED Then
            _Ferr5()
            _Clica("0", GUICtrlRead($cmbLotes), 0)
            _Ferr6()
            _Clica("0", GUICtrlRead($cmbLotes), 0)
        EndIf
        If GUICtrlRead($chkAtualizar) = $GUI_CHECKED Then
            _FerrAtualizar()
        EndIf
        #ce ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        ; Check for Stop button being pressed
        If GUIGetMsg() = $btnStop Then _appAtivo()

    WEnd

    GUICtrlSetData($hLabel, "") ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

EndFunc   ;==>_Cuidar

Func _appAtivo()
    ; Set flag to show we should stop
    $appAtivo = 0
EndFunc   ;==>_appAtivo

If you start the function with the "Cuidar" button, you can stop it with either the "Stop" button or the "Esc" HotKey. I hope it is all clear. You will need to delete the lines marked with <<<<<<<<<<<<<< to get back to your normal loop.

You will also see that I have altered your code a little when you check the Checkboxes:

- You need not check If $appAtivo Then every time - if you are in the loop then $appAtivo must be set to 1.

- You need not use == to check the GUICtrlRead value - it is only used to do a case-sensitive comparison of strings.

I hope that sets you on your way. :)

M23

Edit:

Here is a similar code using OnEvent mode and GUIRegisterMsg to detect a click on the "Stop" button like KaFu suggested:

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

Opt("GUIOnEventMode", 1)  ; Change to OnEvent mode

HotKeySet("{ESC}", "_appAtivo")

Global $appAtivo = 0

$hGUI = GUICreate("Test", 500, 500)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Sair")

$btnCuidar = GUICtrlCreateButton("Cuidar", 10, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Cuidar")

$btnStop = GUICtrlCreateButton("Stop", 10, 50, 80, 30)
$hlabel = GUICtrlCreateLabel("", 10, 100, 200, 20)

GUISetState()

GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND")

While 1

    Sleep(10)

WEnd

Func _Sair()
    Exit
EndFunc   ;==>_Sair

Func _Cuidar() ; Routine to make some thinks when button is pressed.

    ; Set flag to show we are running
    $appAtivo = 1
    GUICtrlSetData($hLabel, "Running")

    ; Keep running until $appAtivo is set to 0
    While $appAtivo

        Sleep(10)

    WEnd

    GUICtrlSetData($hLabel, "")

EndFunc   ;==>_Cuidar

Func _appAtivo()
    ; Cancel flag to show we should stop
    $appAtivo = 0
EndFunc   ;==>_appAtivo

Func MY_WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)

    Switch BitAND($wParam, 0xFFFF) ;LoWord = IDFrom
        Case $btnStop
            Switch BitShift($wParam, 16) ;HiWord = Code
                Case $BN_CLICKED
                    $appAtivo = 0
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc;==>WM_COMMAND

If you do not understand GUIRegisterMsg, try reading the tutorial in the Wiki here - I can thoroughly recommend it (because I wrote it :( )!

Edited by Melba23

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Melba23,

Everything is clar for me now, except Func MY_WM_COMMAND, I confess (hehe).

But I'll read the all wiki page to understand completly (thanks for wrote :()

For a little read, i can see that GUIRegisterMsg its better, and have to leave CPU/Memory free in major time, because only acts when event is dispared.

But, I need to learn so much in MSDN to understand all windows message, and manipulate correctly them.

Well, I'm not lazy and I love performance, so I'll deepen on it, but for now... I'll use GUIGetMsg Method.

Thanks for you great support, now I can continue job.

[]'s

Nei

Share this post


Link to post
Share on other sites

If you do not understand GUIRegisterMsg, try reading the tutorial in the Wiki here - I can thoroughly recommend it (because I wrote it :( )!

Oh, didn't saw that you've posted it to the wiki... changed link in my sig :)...

Share this post


Link to post
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
Sign in to follow this  
Followers 0