label does not pass through vertically stacked hotkeys? Topic is solved

Get help with using AutoHotkey and its commands and hotkeys
askyq

label does not pass through vertically stacked hotkeys?  Topic is solved

24 Aug 2018, 16:43

When I run this code and click the button only the first msgbox shows. But press F1 and the second messagebox shows up. Somehow the label thread is interrupted by vertically stacked hotkeys but the F1 hotkey thread passes through the two hotkeys below it. Why is that? Is there a workaround to make the label thread pass through?

Code: Select all

gui, add, button, gbutton, test
gui, show
return

button:
msgbox, a
F1::
F2::
F3::
msgbox, b
exitapp
Helgef
Posts: 4479
Joined: 17 Jul 2016, 01:02
Contact:

Re: label does not pass through vertically stacked hotkeys?

25 Aug 2018, 03:45

Why is that?
auto execute section wrote:Note: While the script's first hotkey/hotstring label has the same effect as return, other hotkeys and labels do not.
hence, it works as you want if you have another hotkey defined above the label, eg,

Code: Select all

gui, add, button, gbutton, test
gui, show

esc::exitapp

button:
msgbox, a
F1::
F2::
F3::
msgbox, b
exitapp
Cheers.
User avatar
jackdunning
Posts: 122
Joined: 01 Aug 2016, 18:17
Facebook: https://www.facebook.com/ComputorEdgeEBooks/posts
Contact:

Re: label does not pass through vertically stacked hotkeys?

25 Aug 2018, 03:49

Label names merely act as markers within scripts ("Understanding Label Names and Subroutines") and do not stop processing unless a subroutine contains the Return command. Hotkey and Hotstring definitions always stop regular AutoHotkey command processing such as subroutines and the Auto-Execute section, although invisible to other preceding stacked blank Hotkey and Hotstring definitions, respectively—such as shown in your example. (Not actually invisible, but merely a technique for assigning the same output to multiple Hotkeys or Hotstrings.)

See the correction below:
jackdunning wrote:I should alter my post to state that only the Auto-Execute section terminates processing when encountering a Hotkey/Hotstring definition.
Last edited by jackdunning on 27 Aug 2018, 15:34, edited 1 time in total.
askyq

Re: label does not pass through vertically stacked hotkeys?

25 Aug 2018, 06:29

Helgef wrote:
Why is that?
auto execute section wrote:Note: While the script's first hotkey/hotstring label has the same effect as return, other hotkeys and labels do not.
hence, it works as you want if you have another hotkey defined above the label
Thank you Helgef for the answer and reference. So the effect was documented after all.

I'm curious: Why is AutoHotkey designed that way? Is that a feature intentionally added to AutoHotkey because it is somehow useful? Or is it merely a necessary feature because of how Windows works or something?
Helgef
Posts: 4479
Joined: 17 Jul 2016, 01:02
Contact:

Re: label does not pass through vertically stacked hotkeys?

25 Aug 2018, 07:37

Why is AutoHotkey designed that way? Is that a feature intentionally added to AutoHotkey because it is somehow useful?
Probably it is done this way to avoid the need to end the auto execute section with a return. Eg, you do not need to put a return above the hotkey in this script,

Code: Select all

a::
	msgbox
return
askyq

Re: label does not pass through vertically stacked hotkeys?

25 Aug 2018, 08:35

Helgef wrote:Probably it is done this way to avoid the need to end the auto execute section with a return.
Ok, I can see some use for that. Though not below an auto execute section that already end with `return` like in my example.

I think this rule would make more sense:
If the auto-execution section is not ended with Return then the script's first hotkey/hotstring label has the same effect as return. Later hotkeys and labels do not have that effect.
But I suppose requesting that change is a non-starter since it could have unpredictable results in existing scripts.
lexikos
Posts: 7141
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: label does not pass through vertically stacked hotkeys?

25 Aug 2018, 17:19

jackdunning wrote:Hotkey and Hotstring definitions always stop regular AutoHotkey command processing such as subroutines and the Auto-Execute section,
Not true. See Helgef's quote.
askyq wrote:If the auto-execution section is not ended with Return then ...
If there's no return, how do we know at what point the auto-execute section is intended to end?

Return is not a structural marker, but an imperative statement; that is, it has an effect only if executed. Analyzing the code before it executes (such as when the first hotkey/hotstring is parsed) to find the "end" of the auto-execute section (or any subroutine) is deceptively complex. For example, the auto-execute section might "end" with an infinite loop (if the loop never exits, there need not be a return), or an if-else where both branches return, or exit rather than return. Or it might goto a different part of the script that does return or exit.

Pass-through works even for the first hotkey/hotstring if you place the label immediately above it:

Code: Select all

gui, add, button, gbutton, test
gui, show
return

button:
F1::
F2::
F3::
if (A_ThisLabel = "button")
    msgbox, a
msgbox, b
exitapp
askyq

Re: label does not pass through vertically stacked hotkeys?

26 Aug 2018, 05:09

lexikos wrote:Pass-through works even for the first hotkey/hotstring if you place the label immediately above it
Useful, thanks.
lexikos wrote:
askyq wrote:If the auto-execution section is not ended with Return then ...
If there's no return, how do we know at what point the auto-execute section is intended to end?
I don't know and your examples convince me of the complexity. But my (naive) suggestion was for when there *is* a Return. I was thinking only of "simple" cases like my example script, where the auto-execute section has no goto and end with a non-branched Return. But I get that AutoHotkey would then need to define and document a simple/non-simple distinction. Complexity seeps back in.

The current rule caught me by surprise though, since it can kick in far down in a script, below an auto-execute section that already end with a Return and below multiple other labels and functions.

Simpler if hotkey/hotstring lines *never* had the same effect as return! But a no go because backwards incompatible. Right?
User avatar
jackdunning
Posts: 122
Joined: 01 Aug 2016, 18:17
Facebook: https://www.facebook.com/ComputorEdgeEBooks/posts
Contact:

Re: label does not pass through vertically stacked hotkeys?

27 Aug 2018, 14:33

lexikos wrote:Not true. See Helgef's quote.
I should alter my post to state that only the Auto-Execute section terminates processing when encountering a Hotkey/Hotstring definition. In subroutines, my testing shows that Hotkey/Hotstring definitions do indeed become invisible (pass through) when no action or text replacement appears to the right of the ::. However, unless I'm missing something, any Hotkey action on the same line (which does run) or a standard Hotstring with replacement text does stop processing. I suppose this is due to the Return being assumed in a single-line Hotkey.

Thank you for the clarification.
lexikos
Posts: 7141
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: label does not pass through vertically stacked hotkeys?

27 Aug 2018, 22:19

No, you are still mistaken. Again, see Helgef's quote. Take it at face value: the first hotkey/hotstring acts as return. Executing this line will cause any subroutine to return. It may or may not be executed by the auto execute thread or any other.

Hotkeys with same line action are no different to multi line hotkeys with return. Excluding the first hotkey/hotstring and auto replace hotstrings, labels do not "stop processing". Processing "stops" when return is executed, after the body of the subroutine (such as the hotkey action) is executed. For example, pressing ^1 executes all three hotkey actions:

Code: Select all

MsgBox Auto-execute section
^1::  ; This acts as return.
MsgBox ^1  ; Not shown unless you press the hotkey.
; There is no return here.
^2::  ; This does not "stop processing".
MsgBox ^2  ; Shown if you press ^2 OR ^1.
^3::MsgBox ^3  ; ^3:: does not "stop processing".
; There is an implicit return in the above AFTER MsgBox.
Auto replace hotstrings act as a label and return, with nothing else, since replacement is handled internally, not by script. It could be said that the label itself does not "stop processing", but rather that the hotstring's action acts as return and has no other effect when executed directly. (But I think that's splitting hairs.)
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: label does not pass through vertically stacked hotkeys?

27 Aug 2018, 23:21

- I wrote a script to try to confirm/summarise the info so far.

Code: Select all

MsgBox, 0
;auto-execute section ends here (because of a hotkey label below)
;(hotkey labels by themselves are usually fallen through)
;(hotkey labels plus code 'one-liners' are usually fallen into but not fallen out of)
q::
MsgBox, 1
w::
MsgBox, 2
e::MsgBox, 3
MsgBox, 4
r::MsgBox, 5
MsgBox, 6

;hotkey and MsgBoxes triggered
;q 1 2 3
;w 2 3
;e 3
;r 5
;note: the line 'e::MsgBox, 3' contains an implicit return, thus: although it can be fallen into, it cannot be fallen out of
- @askyq: This would be a simple workaround? Or not?

Code: Select all

Gosub MySub
return

MySub:
q::
MsgBox, 1
return
- @jackdunning: Nice to see you on the forum.

[EDIT:]
changed: ;(hotkey labels plus code 'one-liners' are never fallen through)
to: ;(hotkey labels plus code 'one-liners' are usually fallen into but not fallen out of)
Last edited by jeeswg on 28 Aug 2018, 09:39, edited 2 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
lexikos
Posts: 7141
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: label does not pass through vertically stacked hotkeys?

28 Aug 2018, 03:06

jeeswg wrote:;(hotkey labels plus code 'one-liners' are never fallen through)
You are misrepresenting the facts. I just explained and we both demonstrated that execution falls through the hotkey label and executes the hotkey action. Anyone who thinks there will be no fall-through will be unpleasantly surprised.

Execution never "falls through" return or Exit or ExitApp; that would clearly contradict the documented effects of those statements. One-line hotkeys contain return. This is what users should consider, not inaccurate conclusions based on these simple facts, such as "one-liners are never fallen through".

There are contrived situations where execution can pass from one one-line hotkey into the next: when a control flow statement transfers control or otherwise prevents execution of return.

Code: Select all

^1::if M(1)
^2::loop % M(2)
^3::M(3)

M(m) {
    MsgBox % m
    return 0
}
Equivalent to:

Code: Select all

^1::
   if M(1)
      return
^2::
   loop % M(2)
      return
^3::
   M(3)
   return

M(m) {
    MsgBox % m
    return 0
}
In fact, that can also be used as a workaround (but I wouldn't recommend it).

Code: Select all

MsgBox 0
if false  ; 'Cancels' the implicit return before the first hotkey.
^1::MsgBox 1
askyg

Re: label does not pass through vertically stacked hotkeys?

28 Aug 2018, 07:58

This is my takeaway after reading through comments up until and including this one by Lexikos.

Rules
1. Execution never falls through return or Exitor ExitApp.
2. One-line hotkeys contain an implicit return at the end of the line.
3. The script's first hotkey/hotstring label has the same effect as a return.
4. Exception to 3: execution of a label placed right above the script's first hotkey label does fall through the hotkey label.
5. The script's later hotkey/hotstring labels do not have the same effect as a return.

Example scripts

1. Execution never falls through return or Exit or ExitApp.

Code: Select all

return     ;or exit or exitapp
msgbox, a  ;not auto-executed on script start
2. One-line hotkeys contain an implicit return at the end of the line.

Code: Select all

F1:: var := 1  ;the end of this line returns
msgbox, a      ;hence this msgbox is not executed on hotkey F1 press

3. The script's first hotkey/hotstring label has the same effect as a return.

Code: Select all

F1:: msgbox, a  ;msgbox not auto-executed on script start since the F1 hotkey label returns

Code: Select all

gui, add, button, gbutton, test
gui, show
return

button:
var := 1
F1::
msgbox, a  ;msgbox not executed on button "test" press
           ;because the script's first hotkey label F1 returns
4. Exception to 3: execution of a label placed right above the script's first hotkey label does fall through the hotkey label.

Code: Select all

gui, add, button, gbutton, test
gui, show
return

button:
F1::
msgbox, a  ;msgbox is executed on button "test" press
5. The script's later hotkey/hotstring labels do not have the same effect as a return.

Code: Select all

gui, add, button, gbutton, test
gui, show
return

F2:: msgbox, b

button:
var := 1
F1::
msgbox, a  ;executed on button "test" press
Notes
Rule 3 can be easy to miss since it can apply even far down in a script, below an auto-execute section that already ended with an explicit return and below multiple other labels and functions if that is where the script's first hotkey/hotstring label is placed.

Therefore if the user wants a previous label to fall through a hotkey label below it they must manually check if it is the script's first hotkey label and in that case add a workaround. For example by making use of rule 4. Or with a goto jump:

Code: Select all

gui, add, button, gbutton, test
gui, show
return

button:
var := 1
goto F1
F1::       ;script's first hotkey/hotstring label
msgbox, a  ;executed when button "test" is pressed

(Q) Why does AutoHotkey have rule 3? Why doesn't the script's first hotkey/hotstring label behave exactly as all other hotkey/hotstring labels?
(A) Some say it was probably added to avoid the need to end the auto execute section with a return.

(Q) Is that a good enough reason to have Rule 3?
(A) Arguably not. But simply removing rule 3 now is backwards incompatible, meaning it can have bad effects in older scripts that rely on rule 3, which seems like a good enough reason to keep rule 3 on by default.

(Q) Why not enhance AutoHotkey with a directive to optionally disable Rule 3? Users could then add it to their script template and never again have to manually perform the task of checking which hotkey/hotstring label is the first in the script. Something like

Code: Select all

#FirstHotkeyReturn off
(A) Interesting suggestion!
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: label does not pass through vertically stacked hotkeys?

28 Aug 2018, 09:42

- I've fixed the post above. I needed a description for: a line that you can fall into, but not fall out of.
- Thanks for the interesting examples.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask For Help”

Who is online

Users browsing this forum: asundrus, viv, XMCQCX and 49 guests