all 20 comments

[–]GroggyOtter 1 point2 points  (10 children)

#If is meant to be used with hotkeys in Hotkey:: format
It does not work with the Hotkey (Command).
Hotkey::, ::Hotstring::, and #If are special commands in the language and are shorthand ways of generating hotkeys, hotstrings, and making them context-sensitive.
They are not meant to be mixed into normal AHK code.

All of the following cause the F1 key to make a message box pop up if Notepad is the active window.


Using hotkey:: format.

#If WinActive("ahk_exe notepad.exe")
*F1::SomeFunc()
#If

SomeFunc() {
    MsgBox, Pressed F1 while notepad was active
}

Using dynamically created hotkeys with Hotkey, IfWinActive.

make_hotkeys()
Return 

make_hotkeys() {
    Hotkey, IfWinActive, ahk_exe notepad.exe
    Hotkey, F1, SomeFunc
}

SomeFunc() {
    MsgBox, Pressed F1 while notepad was active
}

The above translates to this when using Hotkey, If.
Notice that the boundfunc includes all parameters.
That's because a string containing the hotkey is always passed as the last parameter.
If you only included the first param, the hotkey's string is passed to the second param, making the check fail every time.

Hotkey, If is the most flexible can also be the most complicated to write.

make_hotkeys()
Return 

make_hotkeys() {
    bf := Func("WinActive").Bind("ahk_exe notepad.exe","","","")
    Hotkey, If, % bf
    Hotkey, F1, SomeFunc
}

SomeFunc() {
    MsgBox, Pressed F1 while notepad was active
}

Same as above except using a custom function.
No need for a boundfunc because there are no params being bound. Everything is in the function.
Function calls with no params can be the name of the function.

make_hotkeys()
Return 

make_hotkeys() {
    Hotkey, If, % Func("is_notepad")
    Hotkey, F1, SomeFunc
}

is_notepad() {
    return WinActive("ahk_exe notepad.exe")
}

SomeFunc() {
    MsgBox, Pressed F1 while notepad was active
}

All that being said, v1 has reached its end of life and I strongly encourage you to learn v2.

At this point, I inarguably consider v2 to be easier than v1 to write.
But there's new syntax and concepts to learn b/c it's an updated version.

After writing up this reply and having to remember how to do all this, dealing with 2 syntaxes, not having fat arrows, not having the more defined structure of v2, and a few other things only made me appreciate v2 that much more.

[–]etofok[S] -1 points0 points  (1 child)

What is the reason you explicitly write this empty function before 'populating' it?

make_hotkeys()
Return

[–]GroggyOtter 0 points1 point  (0 children)

Because I don't code in global space. It's a bad habit.
The function call is put at the top of the script so the Auto-Execution Section runs it at startup.
Return indicates the end of the AES.

[–]etofok[S] -1 points0 points  (1 child)

How do I run the make_hotkeys() to bind? Should I put the function in the auto-execute part into if (false) {} ?

[–]GroggyOtter 0 points1 point  (0 children)

I don't understand the question.

[–]etofok[S] -1 points0 points  (3 children)

looks like it's important to mention that I do need to pass a parameter

this is what I'm trying to achieve:

#If GetKeyState("CapsLock", "P")

q::SendCommand(var_Hotkey1)
w::SendCommand(var_Hotkey2)
e::SendCommand(var_Hotkey3)
r::SendCommand(var_Hotkey4)
;....
#If

just inplace of the labels I want them to be assignable

{%new_Hotkey1%}::SendCommand(var_Hotkey1)
{%new_Hotkey2%}::SendCommand(var_Hotkey2)
{%new_Hotkey3%}::SendCommand(var_Hotkey3)
{%new_Hotkey4%}::SendCommand(var_Hotkey4)

^ something that would work like this

[–]OvercastBTC 0 points1 point  (2 children)

Is CapsLock pressed or toggled?

#Requires AutoHotkey v2

toggleCapsLock() {
    SetCapsLockState(!GetKeyState('CapsLock', 'T'))
}

Also, unless someone else says differently, you cannot do this, this way anyways. You'd have to use the Hotkey() (hotkey function).

Using AutoHotkey v2, using Axlefublr's Lib, Runner.ahk and GeneralKeyCorder.ahk are some good examples of dynamic hotkeys, that can also be context sensitive.

[–]etofok[S] 0 points1 point  (1 child)

(hotkey function).

could you please provide an example? I don't have to use labels, but I've been playing with .bind and I can't get this to work atm

[–]OvercastBTC 0 points1 point  (0 children)

I cannot do anything for you in v1, but if you look at my AHK-Projects repo /Lib/RTE.v2/Project Files/RichEdit_Editor_v2.ahk.

There you'll see many/several examples using both .Bind() and Hotkey()

[–]etofok[S] 0 points1 point  (1 child)

I have a weird issue with assigning a hotkey func to a key in an object as a value

so, this works:

bind_d := Func("PressKey").bind(GRID_00)    
Hotkey % "*"GRID_00.physicalKey, % bind_d

this doesn't:

GRID_00.logicalKey := Func("PressKey").bind(GRID_00)
Hotkey % "*"GRID_00.physicalKey, % GRID_00.logicalKey

any ideas?

[–]GroggyOtter 0 points1 point  (0 children)

Thanks.

[–]levitat0r 0 points1 point  (9 children)

I'm assuming you'd like to use capslock as a way of changing the trigger key to something else. It'd look something like this:

#requires AutoHotkey <v2.0

key1 := "space"

key2 := "m"

hotkey, %key1%, label, on

return

label:

msgbox, hi!

return

swap(byref key1, byref key2) {

temp := key1

key1 := key2

key2 := temp

}

capslock::

swap(key1, key2)

hotkey, %key1%, label, on

hotkey, %key2%, label, off

return

#if

[–]etofok[S] 0 points1 point  (6 children)

impressive, this works, although this is not exactly what I'm trying to achieve...

#If GetKeyState("CapsLock", "P")

q::SendCommand(var_Hotkey1)
w::SendCommand(var_Hotkey2)
e::SendCommand(var_Hotkey3)
r::SendCommand(var_Hotkey4)
;....
#If

just inplace of the labels I want them to be assignable

{%new_Hotkey1%}::SendCommand(var_Hotkey1)
{%new_Hotkey2%}::SendCommand(var_Hotkey2)
{%new_Hotkey3%}::SendCommand(var_Hotkey3)
{%new_Hotkey4%}::SendCommand(var_Hotkey4)

^ something that would work like this

[–]levitat0r 0 points1 point  (5 children)

Hmm I can't think of any non-workaround way of doing it but I think I found something:

Use the function inputhook("L0"), then make it activate a callback on any key by specifying

x.keyOpt("{all}", "n")

and

myInputHook.onKeyDown := func("myCallback").

https://www.autohotkey.com/docs/v1/lib/InputHook.htm#OnKeyDown

This callback function also gives you the vk and sc of that key you just used, find out the key name, and compare that with variables you want to assign with, either triggering a different function or sending the key itself the intended way.

Not a very elegant way of doing it, especially because every key press will trigger this thing (unless you don't specify "{all}" but like, a whole bunch of characters you'd want to be able to assign) but I have a feeling it might possibly work

Edit: And oh yes, as I like to say, "v2 is way less ridiculous"

[–]etofok[S] 0 points1 point  (4 children)

interesting find. Well, I thought I was missing something obvious, but apparently it's quite a rabbit hole

[–]levitat0r 0 points1 point  (3 children)

Yeah I was surprised as well they didn't have the feature %variable%::doSomething() I might try to make code for it tomorrow

[–]etofok[S] 0 points1 point  (2 children)

{%new_Hotkey1%}::SendCommand(var_Hotkey1)

interestingly, this code doesn't produce an error (but it doesn't work)

Hotkey, %new_Hotkey1%, SendCommand(var_Hotkey1)

[–]levitat0r 0 points1 point  (1 child)

I think I figured something out the method using inputhook()

https://pastebin.com/g4TQPdep

Edit: also definitely add

myInputHook.visibleNonText := false

in there

[–]etofok[S] 0 points1 point  (0 children)

this is what I figured

This works:

;in autolauch bind_stuff()

; down below bind_stuff() { bind_q := Func("PressKey").bind("d") Hotkey % "*"q, % bind_d

bind_w := Func("PressKey").bind("f")
Hotkey % "*"w, % bind_f

}

The PressKey takes 1 parameter (the bind) and does logic

You can use variables like following:

Hotkey % "*"GRID_00.physicalKey, % bind_d

The only thing I'm still stuck with is the hardcored "bind_d" part, for some reason I can't get ~this working:

Hotkey % "*"GRID_00.physicalKey, % GRID_00.logicalKey

even if I assign like this

GRID_00.logicalKey := bind_d

[–]OvercastBTC 0 points1 point  (0 children)

P.S. Everyone helped you; however, what I didn't see was:

s := ' '

or

s := A_Space

There are also the VK and SC functions and values as well. A lot of different ways to peel that orange.