This more directly shows the odd behaviour of MsgBox:
Code: Select all
global GlobalVariable := 1
OnMessage(0x8000, "msg")
DetectHiddenWindows on
PostMessage 0x8000, , , , % "ahk_id " A_ScriptHwnd
MsgBox % GlobalVariable " (autoexec)"
return
msg() {
GlobalVariable := 2
MsgBox % GlobalVariable " (msg)"
}
There's no expectation that PostMessage will cause a new thread to execute immediately, and it doesn't, but it
appears that way because of the order that the dialogs visually appear on screen.
This is because all commands that display a dialog are designed to flush the message queue prior to displaying the dialog. According to some
comments in the source code, this is to fix an issue where pending events are discarded if a critical thread displays a dialog (due to the dialog function entering a modal message loop and dispatching messages that are supposed to remain in the queue). This is related to the following documented behaviour:
It would be more accurate to say that the thread becomes interruptible and any pending messages are dispatched prior to displaying the dialog.
As this is done by the command which displays the dialog, it is necessarily after the command's own parameters are evaluated; so after the variable is read, as Helgef noted.
guest3456 wrote: ↑24 Aug 2022, 23:50
[using Control] instead of GuiControl, DOES work
If so, it is due to the following.
To improve reliability, a delay is done automatically after every use of this command (except for the sub-commands Style and ExStyle). That delay can be changed via SetControlDelay.
Source: Control - Syntax & Usage | AutoHotkey
However, in my testing the default delay was insufficient, as the auto-execute thread was still within its default
period of uninterruptibility. Adding
Critical Off above
Control made it work consistently. This doesn't work for GuiControl because GuiControl doesn't perform an automatic
sleep.