Function 动态创建函数/子例程的自动热键热键

Function 动态创建函数/子例程的自动热键热键,function,dynamic,hotkeys,autohotkey,subroutine,Function,Dynamic,Hotkeys,Autohotkey,Subroutine,AutoHotkey命令Hotkey允许在运行时创建动态热键,但其语法和文档似乎将其限制为内置或现有标签/子例程,这使得它的用处大大降低: 热键,键名[,标签,选项] 有没有办法让它像普通的硬编码热键一样工作?例如: #z::MsgBox foobar ; Typical, hard-coded hotkey pops up a message-box Hotkey, z, MsgBox foobar ; Nope; complains about missing label “

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

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

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

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

Hotkey, z, MsgBox foobar ; Nope; complains about missing label “MsgBox foobar”
由于手册中的以下行,这似乎是可能的,但不清楚它将如何工作:

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


这就是你要找的吗

#Persistent
#SingleInstance Force
#installKeybdHook

Hotkey, #z, MyLabel

MyLabel:
    MsgBox,OK
Return

在“自动热键”中不可能完全执行您想要的操作。这是我能想到的最接近的方法

调用此文件
Hotkeys.ahk
,并将其放入
mydocuments/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
下面是一个示例脚本,您可以使用它

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

MsgBox(msg) {
    msgbox % msg
}

#Include <Hotkeys>
热键(“e”、“msgbox”、“foobar”) MsgBox(msg){ msgbox%msg } #包括
第一个参数是热键,第二个参数是要调用的函数,之后的所有参数都传递给函数。

这是FakeRainBrigand答案的改进。它的用法完全相同:

Hotkey("x", "Foo", "Bar") ; this defines:  x:: Foo("Bar")
与原来的更改:

  • 通过将处理程序子例程塞入函数,防止意外自动执行处理程序子例程

  • 通过将
    热键
    变量的范围从全局缩小到静态,允许我减少命名空间污染

  • 优化
    fun
    仅在热键定义时查找一次(使用
    Func()
    );在调用时,通过将
    热键
    分成两个对象
    funs
    args
    ,对象查找减少了四到两个

  • 当然,由于对象表示法和变量
    arg*
    语法的原因,这仍然依赖于AutoHotKey的_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
    }
    

    对于较新的ahk版本,现在可以使用函数作为标签参数。看

    显然,我不明白。你能详细介绍一下你要找的是什么吗?上面的例子正是我要找的;一种无需手动为每个动态创建的热键创建带标签的子例程即可执行以下操作的方法:
    hotkey,z,MsgBox foobar
    不可能完全按照您所描述的方式执行。你能给出一个现实的例子来说明你想要做什么吗?@FakeRainBrigand,在提出这个问题的脚本中,我有大约200个热键,它们调用一个函数(具有可选参数),并传递不同的参数。我不能为每一个创建单独的标签/子例程,即使我可以,我也不想这样做,因为这会使添加或删除热键变得困难,而不仅仅是修改一行。通过使用数组和
    A_thishhotkey
    ,我可能能够在当前脚本中解决这个问题,但即使这样做有效,它也不能真正解决函数的动态热键问题(或者动态标签是什么);创建泛型处理程序。它没有修复热键命令的限制,但它是一个令人满意的解决方案。我喜欢您的示例提供了提供不同参数的能力,以便可以调用其他函数。不过需要注意的是,
    Include
    必须移动到脚本的末尾,因为它终止了自动执行部分,因此如果在开始时,对
    热键
    函数的调用永远不会完成。请注意几点。(1) 我必须从函数定义中删除星号才能让它工作(
    Hotkey(hk,fun,p*)
    ⇨ <代码>热键(hk,fun,p)(2)出于某种原因,使用
    E
    作为关联数组的键不起作用(
    A
    B
    Z
    ^E
    +E
    ,等等。这看起来像是AHK数组处理的一个bug(或者它可能是一个特殊的键,但不是我所能找到的;只有
    base
    似乎是特殊的)。星号可以让你传递任意数量的参数,如果你移除它,你只能传递一个(如果这是你所需要的,那没什么大不了的)。不过,如果您愿意,您仍然可以传递数组。此外,请尝试使用小写热键。
    e
    表示“e”键,
    e
    表示Shift-e。
    e
    对我有效。
    e表示“e”键,e
    不;
    +e
    +e
    表示Shift+e,两者都是
    e
    e
    表示e不ork;出于某种原因,它似乎作为键无效。(我使用的是_l1.1.7.1和_l1.0.48.5不支持
    {}
    ,并用
    对象()替换它。
    一点作用也没有。)