Jump to content

How to interrupt a GUI event handler


Lang Zerner
 Share

Recommended Posts

I've got a GUI that lets the user trigger a task that takes anywhere from 10 seconds to several minutes. I'm using OnEvent mode. While the task is executing, event processing seems to be turned off.

I've attached a simplified illustration of the problem. The attached code shows a simple GUI with two buttons: OK and Cancel. The event handler for the OK button triggers an event handler that executes Sleep(100) 50 times, for a total delay of about 5 seconds. The event handler for the Cancel button simply exits the application.

Both buttons do what they should. However, once I press the OK button, the Cancel button has no effect until the OK() handler completes.

It seems that the events are stored in a queue and handled synchronously. I'd like to be able to use the Cancel button to Cancel the OK() event handler, that is, to trigger the Cancel() handler asynchronously. I'd prefer to keep OnEvent mode turned on, since my actual application is pretty heavily event driven. What is a recommended way to implement this sort of asynchronous triggering within an event handler? Is there a way to "watch" the Cancel button from within the OK() handler?

Thanks,

--Lang

event_test.au3

Link to comment
Share on other sites

I'm deleting my reply here. I'm not trying to revise history, but Valik demonstrates in the next reply that GUI events like button presses can interrupt the current execution stream and my comment about threading could only confuse the issue.

Dale

Edited by DaleHohm

Free Internet Tools: DebugBar, AutoIt IE Builder, HTTP UDF, MODIV2, IE Developer Toolbar, IEDocMon, Fiddler, HTML Validator, WGet, curl

MSDN docs: InternetExplorer Object, Document Object, Overviews and Tutorials, DHTML Objects, DHTML Events, WinHttpRequest, XmlHttpRequest, Cross-Frame Scripting, Office object model

Automate input type=file (Related)

Alternative to _IECreateEmbedded? better: _IECreatePseudoEmbedded  Better Better?

IE.au3 issues with Vista - Workarounds

SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y

Doesn't work needs to be ripped out of the troubleshooting lexicon. It means that what you tried did not produce the results you expected. It begs the questions 1) what did you try?, 2) what did you expect? and 3) what happened instead?

Reproducer: a small (the smallest?) piece of stand-alone code that demonstrates your trouble

Link to comment
Share on other sites

Something like this will work:

Opt("GUIOnEventMode", True)

Global $g_bHeavyProcessing = False

Local $hWnd = GUICreate("Test")
Local $idOkay = GUICtrlCreateButton("Okay", 5, 5)
Local $idCancel = GUICtrlCreateButton("Cancel", 50, 50)

GUICtrlSetOnEvent($idOkay, "OnOkay")
GUICtrlSetOnEvent($idCancel, "OnCancel")

GUISetState(@SW_SHOW, $hWnd)

While WinExists($hWnd)
    If $g_bHeavyProcessing Then
        Sleep(5000)
        $g_bHeavyProcessing = False
    EndIf
    Sleep(25)
Wend

Func OnOkay()
    ConsoleWrite("OnOkay()" & @CR)
    $g_bHeavyProcessing = True
EndFunc

Func OnCancel()
    ConsoleWrite("OnCancel()" & @CR)
    Exit
EndFunc

Edit: Provided a real example. If not using the Beta version of AutoIt, replace "True" with "1" and "False" with "0".

Edited by Valik
Link to comment
Share on other sites

Valik, the example you give seems to put the processing for the OK button into the main event loop, while the event handler simply sets a Boolean to indicate that the processing should take place in the loop. It that what you had in mind?

I don't need multi-threading--only one thread/function is executing at a time here--but it sure would be nice if I could start a new event queue I can see new events while executing OK(). Another solution would be to temporarily turn off event mode with Opt("GUIOnEventMode", 0), so I could use GUIGetMsg() while executing OK() (then I'd turn OnEventMode back on before returning to the main loop).

I've attached a better-commented example based on the structure of my real-life script. Sorry if I'm being dense, but can anyone show me a way to duplicate the behavior of this script, but with the Cancel button actually causing execution to stop?

Link to comment
Share on other sites

Valik, the example you give seems to put the processing for the OK button into the main event loop, while the event handler simply sets a Boolean to indicate that the processing should take place in the loop. It that what you had in mind?

Do you really think I would of written the code that way if it wasn't?

I don't need multi-threading--only one thread/function is executing at a time here--but it sure would be nice if I could start a new event queue I can see new events while executing OK().

Then that means more than one function would be executing at the same time, which is more or less what I demonstrated.

Another solution would be to temporarily turn off event mode with Opt("GUIOnEventMode", 0), so I could use GUIGetMsg() while executing OK() (then I'd turn OnEventMode back on before returning to the main loop).

Thats not a solution, that's a recipe for disasaster. Never, ever try to mix the two GUI modes. You will have missed messages at best.

but with the Cancel button actually causing execution to stop?

Did you try my script? I simulated a "long running" operation which left the Cancel button operable. What makes your script so magically special (I didn't look at it) that it won't work using a similar approach?
Link to comment
Share on other sites

Did you try my script? I simulated a "long running" operation which left the Cancel button operable. What makes your script so magically special (I didn't look at it) that it won't work using a similar approach?

I did try it, but I didn't grasp that the Cancel button works even while the Sleep(5000) operation is taking place. I just tried replaceing the Sleep(5000) with the meet of my sample OK() function from event-test2.au3, and I see now that your approach works perfectly. Forgive a poor newbie--I feel like a complete fool now! :"> --and thanks!!!

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