Which "blocking" functions are safe to use in GUIRegisterMsg handler? Eg TrackPopupMenu?

Recommended Posts

tdw 0

tdw 0

I'm looking for information about what is safe to put in a message handler registered with GUIRegisterMsg(), because the help file contains the warning: "blocking of running user functions which executes window messages with commands such as "Msgbox()" can lead to unexpected behavior, the return to the system should be as fast as possible !!!", but doesn't exactly say what "blocking" is or what the "unexpected behaviour" is. (And "unexpected" is not necessarily bad or buggy if you know what it is so it isn't "unexpected" any more!)

The program I am writing has a ReBar containing a Toolbar with buttons, some of which drop-down menus. The buttons/menu commands cause my script to interact with another application eg sending keys, waiting for a dialog to appear, filling in info in the dialog, etc. Thus there are lots of potentially "blocking" functions I want to call in my WM_NOTIFY handler, such as _GUICtrlMenu_TrackPopupMenu() and WinWait(), and I'm wondering which are safe, and when I need to use the dummy control technique to transfer control back to AutoIt's main loop.

Windows functions that can suspend execution of the calling thread eg Sleep(), blocking I/O functions, and GetMessage() in a nested message loop.

Are all of these unsafe in a GUIRegisterMsg() handler, or are any OK? I notice that example code in these forums uses TrackPopupMenu in a message handler - but perhaps that strictly isn't safe?

Thinking about what might happen in each case:

1. (AutoIt functions like WinWait): *IF* the GUIRegisterMsg handler is being run by a recursive invocation of AutoIt's usual main loop, then - apart from normal sequential execution being suspended, the only problem I see is that the handling of further Windows messages might cause deep recursion of AutoIt's main loop (and message loop), and potentially the handler could be executed re-entrantly (which could cause coding headaches). Come to think of it... is there anything that stops GUIRegisterMsg handlers being executed reentrantly anyway by two windows messages that arrive in quick succession?

2. Nested message loops: I would expect this to cause a pause in the things that AutoIt usually does in its main loop in addition to message pumping, eg AdLib functions, checking for pause/quit from the tray icon, etc -- but is it any different when nested message loops occurs in a GUIRegisterMsg handler compared to at other times eg normal menu handling or calling MessageBox() from main line code (see eg example code on DllCall in help file)?

3. Functions causing the calling thread to be suspended: I expect the same effect as in any Windows program, ie program becomes unresponsive and inactive until execution resumed.

In summary:

Functions like TrackPopupMenu are "blocking" by some definitions, but seem to be regarded as OK in GUIRegisterMsg handlers -- is this right or am I skating on thin ice and writing fragile code - risking something "unexpected"?

I accidentally called WinWait() from a GUIRegisterMsg handler, and nothing seemed to go wrong -- was I just lucky, or is my analysis above about why it might have worked correct?

Is reentrance of GUIRegisterMsg handlers possible? (Because if so, I need to be very careful about writing any global data from one.)

I look forward to the commentary and advice of AutoIt experts!

Share this post

Link to post

Share on other sites

monoscout999 9

monoscout999 9

Too much explanation... really too much... i can´t answer your question but you can do the calls outside of the Registered function... setting a variable and checking the variable in the main loop.. let me show you.how to....

Share this post

Link to post

Share on other sites

wraithdu 68

wraithdu 68

As the documentation states, blocking a GUIRegisterMsg function can lead to unexpected results. I take that to mean the consequences are undefined. As such, you're just as likely to have success one day, and turn your computer into a molten pile the next. If you see examples in the help file where there is blocking, you should report it in the "Report Help File Issues Here" thread in this forum.

Take monoscout's advice, or use another method like GuiCtrlSendToDummy (if you have a GUI) from within the message so you can return to the main script quickly.

Share this post

Link to post

Share on other sites

tdw 0

tdw 0

If you see examples in the help file where there is blocking, you should report it in the "Report Help File Issues Here" thread in this forum.

That's easy! The example code on the help page for GUIRegisterMsg() {where it says commands such as "Msgbox()" can lead to unexpected behavior) uses --- you guessed it --- Msgbox()! And presumably the example code works...

Another example: On the help file page for _GUICtrlMenu_TrackPopupMenu() [which I believe to be a blocking function], the example shows the use of _GUICtrlMenu_TrackPopupMenu() within --- you guessed it --- a GUIRegisterMsg() handler! In fact, if you search the help file for example code containing "_GUICtrlMenu_TrackPopupMenu", you find that in every case this blocking function is called from within a GUIRegisterMsg handler, except one where is called in a Windows message handler created by _WinAPI_SetWindowLong(), which (I suspect) is also some kind of abnormal execution environment.

I totally agree with monoscout999 and wraithdu that ignoring warnings about "unexpected behaviour" is asking for trouble so it would be safer to contort my program's logic to avoid (eg) calling TrackPopupMenu from within a GUIRegisterMsg handler. On the other hand, it was much easier to copy from the examples, and when there are so many examples in the AutoIt help file where the warning seems to be disregarded, I wonder what exactly the danger is? Wraithdu is certainly right to advise that I regard "unexpected" as "undefined" even if it seems to work, but perhaps (does anyone know?) the "unexpected" behaviour is actually something quite benign, as long as one is aware and expects it. The writer the the help page for GUIRegisterMsg didn't let us in on what s/he thought we might find "unexpected"! (Cue the Spanish Inquisition... oops, no, this isn't a Python forum :-)

Sorry to go on about this, but I like to keep my code clean and simple (so I can understand it :-), so if the example code is acceptable, and the warning a bit stern, I'd be happy not to have to butcher my apparently working code.

Share this post

Link to post

Share on other sites

Zedna 161

Zedna 161

Too much explanation... really too much... i can´t answer your question but you can do the calls outside of the Registered function... setting a variable and checking the variable in the main loop.. let me show you.how to....

Share this post

Link to post

Share on other sites

Zedna 161

Zedna 161

That's easy! The example code on the help page for GUIRegisterMsg() {where it says commands such as "Msgbox()" can lead to unexpected behavior) uses --- you guessed it --- Msgbox()! And presumably the example code works...

I think that it depends on what message you register by GUIRegisterMsg(). Some messages are safe to slow down (or even block?)

and other are very sensitive to that. I have got experience from my scripts that WM_NOTIFY with some NM_XXX (ListView notifications - it was probably something related LV sorting) is sensitive - listview starts to behave unexpected way (bad header redraw etc.).