动态创建AutoHotkey热键到功能/子例程

Syn*_*ech 7 autohotkey function hotkeys dynamic subroutine

AutoHotkey命令Hotkey允许在运行时创建动态热键,但其语法和文档似乎将其限制为内置或现有标签/子例程,这使得它那么有用:

热键,KeyName [,标签,选项]

有没有办法让它像普通的硬编码热键一样工作?例如:

#z::MsgBox foobar        ; Typical, hard-coded hotkey pops up a message-box

Hotkey, z, MsgBox foobar ; Nope; complains about missing label “MsgBox foobar”
Run Code Online (Sandbox Code Playgroud)

看起来它可能是由于手册中的以下行,但不清楚它是如何工作的:

标签 - 可以使用普通标签和热键/热字符串标签.

Bri*_*and 7

在AutoHotkey中无法完全按照您的要求进行操作.这是我能想到的最接近的方式.

调用此文件Hotkeys.ahk,并将其放入My Documents/AutoHotkey/Lib.或者创建一个名为Lib的文件夹,并将其放在与主脚本相同的目录中.

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
Run Code Online (Sandbox Code Playgroud)

这是一个可以使用它的示例脚本.

Hotkey("e", "msgbox", "foobar")

MsgBox(msg) {
    msgbox % msg
}

#Include <Hotkeys>
Run Code Online (Sandbox Code Playgroud)

第一个参数是热键,第二个参数是要调用的函数,之后的所有内容都传递给函数.


eki*_*pan 7

这是对FakeRainBrigand的回答的改进.它使用完全相同:

Hotkey("x", "Foo", "Bar") ; this defines:  x:: Foo("Bar")
Run Code Online (Sandbox Code Playgroud)

原始变化:

  1. 通过将其放入函数中来防止意外自动执行处理程序子例程.

  2. 允许我通过将变量的范围从全局缩小到静态来减少命名空间污染hotkeys.

  3. 优化:在热键定义时fun仅查找一次(使用Func()); 在调用期间,对象查找降低一点五十六通过分裂hotkeys成两个对象funsargs;

由于Object符号和可变arg*语法,这仍然依赖于AutoLotKey的_L版本.

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
}
Run Code Online (Sandbox Code Playgroud)