【问题标题】:Dynamically Create AutoHotkey Hotkey to Function/Subroutine为函数/子程序动态创建 AutoHotkey 热键
【发布时间】:2012-10-02 19:59:21
【问题描述】:

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”

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

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

【问题讨论】:

  • 显然,我不明白。您能否详细说明您在寻找什么?
  • 上面的例子正是我要找的;一种无需为每个动态创建的热键手动创建标记子例程的方法:Hotkey, z, MsgBox foobar
  • 不可能完全按照您的描述进行。你能举一个你想做什么的现实例子吗?
  • @FakeRainBrigand,在引发此问题的脚本中,我有大约 200 个热键调用函数(具有可选参数),并传递不同的参数。我不能为每个标签/子程序创建单独的标签/子程序,即使我可以,我也不想因为它会增加添加或删除热键,而不仅仅是修改一行。我也许可以通过使用数组和A_ThisHotkey 使用当前脚本来解决这个问题,但即使这样可行,它并不能真正解决函数的动态热键问题(或什​​么动态标签是)。

标签: function dynamic hotkeys autohotkey subroutine


【解决方案1】:

这是你要找的吗?

#Persistent
#SingleInstance Force
#installKeybdHook

Hotkey, #z, MyLabel

MyLabel:
    MsgBox,OK
Return

【讨论】:

    【解决方案2】:

    在 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
    

    这是一个您可以使用的示例脚本。

    Hotkey("e", "msgbox", "foobar")
    
    MsgBox(msg) {
        msgbox % msg
    }
    
    #Include <Hotkeys>
    

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

    【讨论】:

    • 是的,我就是thinking of;创建一个通用处理程序。它不能解决Hotkey 命令的限制,但它是一个令人满意的解决方案。我喜欢您的示例提供了提供不同参数的能力,以便可以调用其他函数。不过需要注意的是,Include 必须移动到脚本的末尾,因为它会终止自动执行部分,因此如果在开头,则永远不会调用 Hotkey 函数。
    • 一些笔记。 (1) 我必须从函数定义中删除星号才能使其工作 (Hotkey(hk, fun, p*)Hotkey(hk, fun, p) (2) 出于某种原因使用E 作为关联数组的键不起作用(ABZ^E+E 等都起作用)。它看起来像是 AHK 的数组处理的一个错误(或者它可能是一个特殊的键,但不是我能找到的;只有 base 似乎是特殊的)。
    • 星号可以让你传递任意数量的参数,如果你去掉它,你只能传递一个(如果你只需要这个就没什么大不了的)。不过,如果你愿意,你仍然可以传递一个数组。
    • 另外,请尝试使用小写热键。 e 表示“e”键,E 表示 Shift-e。 e 为我工作。
    • e means the 'e' key, E 不; +e+E 表示 Shift+EeE 表示 Ee 也不起作用;由于某种原因,它似乎作为密钥无效。 (我使用 _L 1.1.7.1 和 _L 1.0.48.5 不支持 {} 并用 Object() 替换它根本没有做任何事情。)
    【解决方案3】:

    这是对 FakeRainBrigand 答案的改进。用法完全一样:

    Hotkey("x", "Foo", "Bar") ; this defines:  x:: Foo("Bar")
    

    对原作的改动:

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

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

    3. 优化fun 在热键定义时仅被查找一次(使用Func());在调用时,通过将hotkeys 拆分为两个对象funsargs,对象查找减少了四到二;

    这当然仍然依赖于 AutoHotKey 的 _L 版本,因为对象表示法和可变参数 arg* 语法。

    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
    }
    

    【讨论】:

      【解决方案4】:

      使用较新的 ahk 版本,您现在可以使用函数作为标签参数。见https://www.autohotkey.com/docs/commands/Hotkey.htm

      【讨论】:

        猜你喜欢
        • 2018-07-29
        • 2018-05-25
        • 2015-10-10
        • 1970-01-01
        • 2012-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-22
        相关资源
        最近更新 更多