AutoHotKey键序列,不仅仅是单键热键

35

我并不愚蠢... 真的。 如何在AutoHotKey中映射键序列(例如:Ctrl + QF)。

我已经完成了Ctrl + Q

^q::

我甚至拥有F键:

f::

帮助文件中的示例甚至展示如何连续执行两个按键:

Numpad0 & Numpad1::

但它无法与以下内容一起使用:

^q & f ::

或者是其中的任何一个:

LCtrl & q & f::
^q & ^f::
^q^f::
^qf::

当我想要通过按键序列触发某个操作时,如何在其中使用Ctrl键?我尝试过使用HOTSTRING,但是无法在这种情况下包含Ctrl字符!

6个回答

31

好的,答案似乎是:

^q::
Input Key, L1
if Key=f
...some code here...
return

1
我过去曾经用一种有效但不太优美的方式来处理这个问题。我喜欢你的方法,已经将其与Progress命令相结合,制作了漂亮的键序列菜单,比如我用来启动浏览器的菜单 **在这里**。感谢你提供更好的方法! - ajk
1
这让我的Ctrl键在尝试几次后出现了问题,例如我不能再按Ctrl-Shift-Esc了。 - BornToCode

5

如果有人在寻找类似的内容,但实际上只想使用CtrlQ+CtrlF组合键,并且仅当Ctrl键一直按住时(因此,对某些人来说,这可能看起来像CtrlQ+F),那么以下就是如何做到这一点:

$Ctrl::Send {Ctrl Down}
$Ctrl UP::
    ChordIsBroken := True
    Send {Ctrl Up}
    Return
^q::
    ChordIsBroken := False
    Input, OutputVar, L1 M
    If (!ChordIsBroken && Asc(OutputVar) = 6)
    {
        MsgBox "Hello, World!"
    }
    Else
    {
        SendInput %OutputVar%
    }
    Return

请查看https://superuser.com/a/725303/145431,了解我的解释。


2
或者您可以这样做:
q & f::
    if GetKeyState("Control") {
        ; Do something
        return
    }
    return

我认为这比使用上述的输入键和L1更易读。


7
& 符号表示需要同时按下两个键。由于 OP 在大写字母中指定了“顺序”,因此此答案不适用。 - horta

1

这会捕获 CTRL+F。如果此时按住 Q,您的代码将触发。

^f::
    If GetKeyState("q", "p") {
        MsgBox test
    } Else {
        Send ^f
    }
return

2
OP需要一系列的按键。这个答案需要同时按下多个按键。 - horta

0
所选答案很好,但在找到这个答案之前,我花了整整一晚上写自己的解决方案,所以...
以下是我过度设计的解决方案 -
SequenceRegister() {
    registeredHook := 0
    inputLen := 0
    actions := Map()

    return SequenceClosure

    SequenceClosure(seq := "", ActionCb := () => true) {
        if (!registeredHook) {
            h := InputHook("BI")
            h.KeyOpt("{All}", "N")
            h.OnKeyDown := KeyDownHandler
            h.Start()
            registeredHook := h
        }

        actionKey := actions.Count
        actions.Set(actionKey, Action)

        Action(hook, VK, SC) {
            if (SubStr(seq, 1, inputLen) = hook.Input && inputLen < StrLen(seq)) {
                return
            }
            
            if (hook.Input = seq && inputLen = StrLen(seq)) {
                ActionCb()
                return
            }

            actions.delete(actionKey)

            if (actions.Count = 0) {
                Send("{Blind}" . Format("{{}vk{:x}sc{:x}{}}", VK, SC))
                hook.Stop()
                return
            }
        }
    }

    KeyDownHandler(hook, VK, SC) {
        inputLen++
        for key, value in actions.Clone() {
            value(hook, VK, SC)
        }
    }
}

使用方法如下:

Capslock & s::{
    CreateSequence := SequenceRegister()

    CreateSequence("sleep", () => MsgBox("I sleep"))
    CreateSequence("sleed", SleedCb)

    SleedCb() {
        MsgBox("I sleed")
    }
}

这允许注册任意数量的序列,如果没有序列匹配,则重放按下的键。 请注意,此代码仅适用于AHK v2。


0

AutoHotkey v1:

#Requires AutoHotkey v1.1.33

^q:: ctrl_q := true ; assign the Boolean value "true" or "1" to this variable
^q up:: ctrl_q := false

; The #If directive creates context-sensitive hotkeys:

#If (ctrl_q) ; If this variable has the value "true"

    ^a:: MsgBox, Ctrl + Q + A
    
    ^b:: MsgBox, Ctrl + Q + B

    ; ...
    
#If

AutoHotkey v2:

#Requires AutoHotkey v2.0

^q:: ctrl_q := true ; assign the Boolean value "true" or "1" to this variable
^q up:: ctrl_q := false

; The #HotIf  directive creates context-sensitive hotkeys:

#HotIf (ctrl_q := true ) ; If this variable has the value "true"

    ^a:: MsgBox "Ctrl + Q + A"
    
    ^b:: MsgBox "Ctrl + Q + B"

    ; ...
    
#HotIf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接