The AutoHotkey command Hotkey
allows for the creation of dynamic hotkeys at runtime, but its syntax and documentation seems to limit it to built-in or existing labels/subroutines, which makes it much less useful:
Hotkey, KeyName [, Label, Options]
Is there a way to get it to work like regular, hard-coded hotkeys? For example:
#z::MsgBox foobar ; Typical, hard-coded hotkey pops up a message-box
Hotkey, z, MsgBox foobar ; Nope; complains about missing label “MsgBox foobar”
It looks like it might be possible due to the following line from the manual, however it is not clear how it would work:
Label - Both normal labels and hotkey/hotstring labels can be used.
Doing exactly what you want isn't possible in AutoHotkey. This is the closest way I can think of.
Call this file Hotkeys.ahk
, and put it in My Documents/AutoHotkey/Lib
. Alternatively make a folder called Lib, and put it in the same directory as your main script.
Hotkeys := {}
Hotkey(hk, fun, p*) {
global hotkeys
hotkeys[hk] := {}
hotkeys[hk].fun := fun
hotkeys[hk].p := p
Hotkey, %hk%, HandleHotkey
}
HandleHotkey:
hotkeys[A_ThisHotkey].fun(hotkeys[A_ThisHotkey].p*)
return
Here's an example script that you could use it with.
Hotkey("e", "msgbox", "foobar")
MsgBox(msg) {
msgbox % msg
}
#Include <Hotkeys>
The first parameter is the hotkey, the second is the function to call, and everything after that is passed to the function.
This is a refinement of FakeRainBrigand's answer. It is used exactly the same:
Hotkey("x", "Foo", "Bar") ; this defines: x:: Foo("Bar")
Changes from the original:
Prevent accidental auto-execute of the handler subroutine by tucking it into the function.
Allowing me to reduce namespace pollution by narrowing the scope of the hotkeys
variable from global to static.
Optimizations: fun
is looked up only once (using Func()
) at hotkey definition time; At invocation time, object lookups reduced four to two by splitting hotkeys
into two objects funs
and args
;
This still relies of course on the _L version of AutoHotKey because of Object notation and variadic arg*
syntax.
Hotkey(hk, fun, arg*) {
Static funs := {}, args := {}
funs[hk] := Func(fun), args[hk] := arg
Hotkey, %hk%, Hotkey_Handle
Return
Hotkey_Handle:
funs[A_ThisHotkey].(args[A_ThisHotkey]*)
Return
}
Is this what you are looking for?
#Persistent
#SingleInstance Force
#installKeybdHook
Hotkey, #z, MyLabel
MyLabel:
MsgBox,OK
Return