Take the 2-minute tour ×

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.

share|improve this question
Apparently, I'm not getting it. Could you give more detail about what you are looking for? –  Robert Ilbrink Oct 12 '12 at 15:31
The example above is exactly what I am looking for; a way to do the following without having to manually create a labeled subroutine for each and every hotkey dynamically created: Hotkey, z, MsgBox foobar –  Synetech Oct 12 '12 at 15:42
It's not possible to do exactly how you describe. Can you give a realistic example of what you want to do? –  FakeRainBrigand Oct 13 '12 at 2:44
@FakeRainBrigand, in the script that brought this issue up, I have ~200 hotkeys that call a function (which has optional arguments), passing it different parameters. I can’t create separate labels/subroutiens for each and every one, and even if I could, I don’t want to because it would make it difficult to add or remove hotkeys instead of just modifying a single line. I may be able to work around this with the current script by using arrays and A_ThisHotkey, but even if that works, it doesn’t really address the issue of dynamic hotkeys to functions (or what dynamic labels are). –  Synetech Oct 13 '12 at 4:47
add comment

3 Answers

up vote 3 down vote accepted

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


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.

share|improve this answer
Yup, this is what I was thinking of; creating a generic handler. It doesn’t fix the Hotkey command’s limitation, but it’s a satisfactory solution. I like that your example provides the ability to supply different arguments so that other functions can be called. One note though, the Include has to be moved to the end of the script because it terminates the auto-execute section, so the calls to the Hotkey function are never done if it’s at the start. –  Synetech Oct 13 '12 at 18:50
A couple of notes. (1) I had to remove the asterisk from the function definition in order to get it to work (Hotkey(hk, fun, p*)Hotkey(hk, fun, p) (2) For some reason using E as the key to the associative array does not work (A, BZ, ^E, +E, etc. all work). It looks like a bug with AHK’s array handling (or maybe it’s a special key, but not as far as I can find; only base seems to be special). –  Synetech Oct 14 '12 at 1:03
The asterisk lets you pass any number of parameters, if you remove it, you can only pass one (not a big deal if that's all you need). You could still pass an array if you like, though. –  FakeRainBrigand Oct 14 '12 at 13:56
Also, try using lowercase hotkeys. e means the 'e' key, E means Shift-e. e works for me. –  FakeRainBrigand Oct 14 '12 at 13:58
e means the 'e' key, E Nope; +e and +E mean Shift+E, both e and E mean E. e doesn’t work either; for some reason it seems to be invalid as a key. (I’m using _L and _L doesn’t support {} and replacing it with Object() did nothing at all.) –  Synetech Oct 14 '12 at 16:12
add comment

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:

  1. Prevent accidental auto-execute of the handler subroutine by tucking it into the function.

  2. Allowing me to reduce namespace pollution by narrowing the scope of the hotkeys variable from global to static.

  3. 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
share|improve this answer
add comment

Is this what you are looking for?

#SingleInstance Force

Hotkey, #z, MyLabel

share|improve this answer
No. MyLabel already exists in you example. –  Synetech Oct 12 '12 at 15:06
add comment

Your Answer


