[1.1.34.04] Routine triggered by ChooseString doesn't change global variable

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Descolada
Posts: 1202
Joined: 23 Dec 2021, 02:30

[1.1.34.04] Routine triggered by ChooseString doesn't change global variable

24 Aug 2022, 10:14

[Moderator's note: Topic moved from Bug Reports.]

Code: Select all

global GlobalVariable := 1
Gui New,, Test GUI
Gui Add, DropDownList, gDDLTest vDDLTest, Selection1|Selection2
Gui, Show

gosub ExecuteRoutine
return

DDLTest:
    global GlobalVariable
    GlobalVariable := 2
    MsgBox, Inside DDLTest routine: %GlobalVariable%
    return

ExecuteRoutine:
    GuiControl, ChooseString, DDLTest, |Selection2
    ;gosub DDLTest ; if the previous line is replaced with this, everything works okay
    MsgBox, ExecuteRoutine: %GlobalVariable%
    ExitApp
Expected behaviour: both messageboxes to show the same number
Actual behaviour: first MsgBox shows 2 (correct), second shows 1 (incorrect)

EDIT: I removed "super-" from the thread title... (please see first reply in this topic)
Last edited by Descolada on 24 Aug 2022, 23:31, edited 2 times in total.
joefiesta
Posts: 502
Joined: 24 Jan 2016, 13:54
Location: Pa., USA

Re: [1.1.34.04] Routine triggered by ChooseString doesn't change super-global variable

24 Aug 2022, 14:30

something certainly appears wrong, but I don't know what it is.

However, after figuring out what is going on (I've never used some of the commands),
I did realize that the author is confusing the issue. The GLOBAL statements have nothing to do with the problem. Remove them and the same results occur.

IMHO, The fact that a super-global variable is created is completely irrelevant because there are no functions in the script.
Descolada
Posts: 1202
Joined: 23 Dec 2021, 02:30

Re: [1.1.34.04] Routine triggered by ChooseString doesn't change super-global variable

24 Aug 2022, 23:29

@joefiesta, you are correct that the super-global isn't actually relevant here, because routines should be able to access regular global variables without the "global" declaration beforehand. But since I wanted to be sure something funky is going on and my actual app requires super-global, I included it here as well.
guest3456
Posts: 3469
Joined: 09 Oct 2013, 10:31

Re: [1.1.34.04] Routine triggered by ChooseString doesn't change global variable

24 Aug 2022, 23:50

interestingly

adding hwndHDDL to the DDL options and using either:

Code: Select all

Gui Add, DropDownList, hwndhDDL gDDLTest vDDLTest, Selection1|Selection2
;.........

Control, ChooseString, Selection2,, ahk_id %hDDL%
;or
Control, Choose, 2,, ahk_id %HDDL%
instead of GuiControl, DOES work

Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: [1.1.34.04] Routine triggered by ChooseString doesn't change global variable

25 Aug 2022, 01:43

The auto-execute section ( :arrow: thread) isn't interrupted on the GuiControl, ChooseString, DDLTest, |Selection2 line, it is interrupted on MsgBox, ExecuteRoutine: %GlobalVariable%, after GlobalVariable has been read. (this isn't a bug)

Cheers.
Descolada
Posts: 1202
Joined: 23 Dec 2021, 02:30

Re: [1.1.34.04] Routine triggered by ChooseString doesn't change global variable

25 Aug 2022, 08:02

@Helgef, you are indeed correct. But this is still unexpected/unintuitive behavior for which perhaps the documentation could be improved (a small note under ChooseString perhaps?)...
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: [1.1.34.04] Routine triggered by ChooseString doesn't change global variable

26 Aug 2022, 03:36

a small note under ChooseString perhaps?
It is nothing specific to ChooseString, it is about threads and interruptions. If you need interruptions to occur at certain points, you should manage it. If your code doesn't manage interruptions, you should design your code such that it doesn't depend on when interruptions occur.
But this is still [...] unintuitive behavior
I agree that it is unintuitive, perhaps even unfortunate, that the msgbox in ExecuteRoutine shows after the one in the gui event routine. But this wasn't really your issue, I believe.

Cheers.
lexikos
Posts: 9690
Joined: 30 Sep 2013, 04:07
Contact:

Re: [1.1.34.04] Routine triggered by ChooseString doesn't change global variable

01 Sep 2022, 04:19

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:
A critical thread becomes interruptible when a message box or other dialog is displayed.
Source: Critical - Syntax & Usage | AutoHotkey
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.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Google [Bot], peter_ahk and 373 guests