Dynamically Create AutoHotkey Hotkey to Function/S

2020-05-29 01:02发布

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.

3条回答
仙女界的扛把子
2楼-- · 2020-05-29 01:30

Is this what you are looking for?

#Persistent
#SingleInstance Force
#installKeybdHook

Hotkey, #z, MyLabel

MyLabel:
    MsgBox,OK
Return
查看更多
我命由我不由天
3楼-- · 2020-05-29 01:37

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.

查看更多
神经病院院长
4楼-- · 2020-05-29 01:39

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
    Return
Hotkey_Handle:
    funs[A_ThisHotkey].(args[A_ThisHotkey]*)
    Return
}
查看更多
登录 后发表回答