Page 1 of 1

Labels and #if

Posted: 29 Apr 2020, 06:47
by Scr1pter
Hi,

I really would like the possibility to use the same label in a script, placed in different #if blocks.
For hotkey labels this already works.

Here a simple example just to demonstrate how the test script basically works:

Code: Select all

;Main Script_Labels
#SingleInstance, Force
#include Joystick_Functions.ahk

Select:
Send 1
return

Select+Cross:
Send 2
return

Code: Select all

;Joystick_Functions

Joy11::
while GetKeyState("Joy11") ; While Joy11 is being pressed:
{
  if GetKeyState("Joy2") ; If Joy2 is also pressed:
  {
    blocked := true ; Disable Joy11 functionality
    GoSub, Select+Cross ; Run label for both buttons
    KeyWait, Joy2 ; Wait until Joy2 has been released
  } 
}
KeyWait, Joy11 ; Wait until Joy11 has been released
if !(blocked) ; If Joy2 was not pressed
{
  GoSub, Select ; Run label for the 1 button
}
Sleep, 20
blocked := false ; Reset value
return
It's impossible to use #ifs in the main script, because AHK claims the duplicate label:

Code: Select all

;Main Script_Labels
#SingleInstance, Force
#include Joystick_Functions.ahk

#if WinActive("ahk_class Notepad++")

Select:
Send 1
return

Select+Cross:
Send 2
return

#if

#if WinActive("ahk_class Notepad")

Select:
Send 3
return

Select+Cross:
Send 4
return

#if
The only work-around (as far as I know) is this:

Code: Select all

;Joystick_Functions

Joy11::
while GetKeyState("Joy11") ; While Joy11 is being pressed:
{
  if GetKeyState("Joy2") ; If Joy2 is also pressed:
  {
    blocked := true ; Disable Joy11 functionality
    Run_Label("Select+Cross") ; Execute function to run label depending on button and application
    KeyWait, Joy2 ; Wait until Joy2 has been released
  } 
}
KeyWait, Joy11 ; Wait until Joy11 has been released
if !(blocked) ; If Joy2 was not pressed
{
  Run_Label("Select") ; Execute function to run label depending on button and application
}
Sleep, 20
blocked := false ; Reset value
return

Run_Label(button)
{
  if WinActive("ahk_class Notepad++")
  {
    GoSub, %button%_notepad++
  }
  if WinActive("ahk_class Notepad")
  {
    GoSub, %button%_notepad
  }
}

Code: Select all

;Main Script_Labels
#SingleInstance, Force
#include Joystick_Functions.ahk

Select_notepad++:
Send 1
return

Select+Cross_notepad++:
Send 2
return

Select_notepad:
Send 3
return

Select+Cross_notepad:
Send 4
return
I clearly prefer the #if-version which unfortunately does not work (yet).
Thanks for reading!

Cheers!

Re: Labels and #if

Posted: 29 Apr 2020, 08:44
by guest3456
ummm, you have the #ifs attached to regular labels, but thats wrong. they are only attached to hotkey labels. likely your code logic is wrong

Re: Labels and #if

Posted: 29 Apr 2020, 09:29
by swagfag
i think hes advocating for allowing the use of #If on regular labels as well, but i dont see the point. the same can be achieved using functions and assoc arrays, probably way more easily too

Re: Labels and #if

Posted: 29 Apr 2020, 11:35
by Scr1pter
guest3456 wrote:
29 Apr 2020, 08:44
ummm, you have the #ifs attached to regular labels, but thats wrong. they are only attached to hotkey labels. likely your code logic is wrong
Uhm that's exactly what I wrote.
"It's impossible to use #ifs in the main script, because AHK claims the duplicate label:"
I know that the script, which I posted, doesn't work.
My request/wish was to make it workable.

@swagfag :
Yes, there are also other ways, but why not being able to use the same method which is available for hotkey labels?

Cheers!

Re: Labels and #if

Posted: 29 Apr 2020, 14:17
by guest3456
sorry my mistake, i thought this was in Bug Reports

Re: Labels and #if

Posted: 29 Apr 2020, 19:39
by swagfag
basically it boils down to 2 things:
A. the exact same thing(and more) can be achieved with arrays and functions with less copypasting

Code: Select all

JoyMap.addKeybind("Notepad++", 1, 2)
JoyMap.addKeybind("Notepad", 3, 4)
...
JoyMap.sendIfActive("select")
JoyMap.sendIfActive("selectcross")
...
class JoyMap
{
    static Map := {}
    
    addKeybind(wndClass, select, selectCross) {
        this.Map[wndClass] := {select: select, selectCross: selectCross}
    }
    
    sendIfActive(whichKey) {
        for wndClass, Keys in this.Map
            if WinActive("ahk_class " wndClass)
                Send % Keys[whichKey]
    }
}
and more importantly, B. v1 is effectively feature frozen save for backports from v2. and this has a 0% chance of getting implemented in v2

Re: Labels and #if

Posted: 30 Apr 2020, 04:52
by Scr1pter
Thank you for your honest words and the interesting code, swagfag!

Cheers!

Re: Labels and #if

Posted: 30 May 2020, 00:01
by lexikos
Scr1pter wrote:
29 Apr 2020, 06:47
For hotkey labels this already works.
FYI, this is not true. #If does not operate on hotkey labels. You can call a hotkey label (or pass its name to SetTimer, Hotkey, Menu, etc.), but which hotkey label ends up executing has nothing to do with #If. Each hotkey definition with :: creates its own label which is independent of both the hotkey and other labels, but the hotkey variant keeps a reference to it and can therefore call it (until the Hotkey command is used to assign a different label, function or object to that variant). In other words, hotkey definitions are permitted to create duplicate labels, but there is nothing special about the labels. A hotkey definition can even create a duplicate of a normal label:

Code: Select all

gosub x  ; 1
ExitApp

x:
MsgBox 1
return
x::MsgBox 2
... but you cannot swap them around. If you could, gosub x would show "2".

#If operates on hotkey variants. When a hotkey is triggered, the program determines which variant to execute based on the condition of each variant. Once a variant is chosen, the label, function or object associated with that variant is executed. Even if a variant was created with ::, if it has been reassigned with the Hotkey command, it no longer has any connection to the original label. If the original label is a duplicate, there is no way to restore it.

It is sometimes possible to reorder the modifier symbols (or add/remove modifiers that do not affect the "sameness" of the hotkey, such as $) so that each hotkey variant has a different label. In that case, even though they are variants of the same hotkey, you can target each label individually.

Code: Select all

ListHotkeys  ; Just x
gosub x
gosub $x
ExitApp

x::MsgBox 1
#If 0
$x::MsgBox 2
Although duplicate labels are permitted for hotkeys, duplicate hotkey variants are not permitted (in cases where the duplication is detected). If you remove the #If 0 in the script above, it will not load regardless of whether the second hotkey has $.


A label is just a point in the code, given a name. Your wish will not be fulfilled.

Re: Labels and #if

Posted: 19 Jun 2020, 04:06
by Rohwedder
Hallo,
replace Labels by Hotstrings:

Code: Select all

#InputLevel 1
q::SendInput, Select
w::SendInput, Cross
#InputLevel 0
#if WinActive("ahk_class Notepad++")
:*:Select::1
:*:Cross::2
#if WinActive("ahk_class Notepad")
:*:Select::3
:*:Cross::4
#if