双击自动热键结果中的键 ctrl+key

double press key in autohotkey results ctrl+key

我的Ctrl键坏了。我正在寻找以下解决方案:

x x = Ctrl-x

其中 x 是任意键(包括 F1、F2、....)

换句话说,如果我连续两次按下任意键(比如x)(即两次按下之间的时间小于一定数量)我可以获得Ctrl-x。

可能吗?

这应该是您要查找的内容。只需将 cooldown 的值替换为您可以接受的按键间隔时间。

CtrlReplacement(key) {
    static cooldown := 1000 ; milliseconds
    If (A_PriorHotkey == A_ThisHotkey && A_TimeSincePriorHotkey < cooldown) {
        Send, {Ctrl Down}{%key%}{Ctrl Up}
    } Else {
        Send, {%key%}
    }
}
keys := ["a","x","c","z","f","b","s","w","q","v","g","h","t","r","e","k","i","]","SPACE","F1","F2","F3","F4"]
For _,key in keys {
    func := Func("CtrlReplacement").Bind(key)
    Hotkey, $%key%, % func
}

一点解释。

我们使用 Hotkey function rather than the typical F1:: (Double-colon label) 语法以便在运行时而不是编译时生成它们(这使得代码更小并且没有重复)。您可以将它们全部写出来,但这会很麻烦。

%key% 之前的 $ 表示虚拟按键不会触发此热键(即热键不会自行触发),因此如果您编写它们全部手动,您需要在每个之前添加 $

然后函数检查热键是否与之前按下的热键相同,以及自上次按下热键以来的时间是否小于预设时间(cooldown)。如果是这样,它会发送 ctrl+组合键。否则,它只发送密钥本身(从而保留密钥的原始功能)。

您还可以调整函数,使其等到冷却时间结束,如果没有再次按下该键,然后并且只有在那时它才会发送原始文件钥匙。尽管这需要更多的技巧。如果那是您的意图,请告诉我,我也可以尽力为您提供帮助。

编辑

无论如何我还是做了那个版本:)

SendDefaultKey(key) {
    Send, {%key%}
}
CtrlReplacement(key) {
    static cooldown := 300 ; milliseconds
    static keyFunctions := []
    If (!keyFunctions.HasKey(key)) {
        keyFunctions[key] := Func("SendDefaultKey").Bind(key)
    }
    func := keyFunctions[key]
    If (A_PriorHotkey == A_ThisHotkey && A_TimeSincePriorHotkey < cooldown) {
        SetTimer, % func, Off
        Send, {Ctrl Down}{%key%}{Ctrl Up}
    } Else {
        SetTimer, % func, -%cooldown%
    }
}
Setup() {
    keys := ["a","x","c","z","f","b","s","w","q","v","g","h","t","r","e","k","i","]","SPACE","F1","F2","F3","F4"]
    For _,key in keys {
        func := Func("CtrlReplacement").Bind(key)
        Hotkey, $%key%, % func
    }
}
Setup()

此版本将 - 对于已映射的键 - 等到冷却时间到期,如果没有再次按下它们的键(并且立即连续),它将发送一次原始键。否则,它将发送 ctrl+key

编辑 2

根据 OP 的评论,这是第三个版本,它为(几乎)所有键盘字符设置了延迟,这使得 ctrl 变体有点多 ergonomic/intuitive。

global keyDelay := 300 ; milliseconds
RunFuncWithDelay(func) {
    SetTimer, % func, -%keyDelay%
}
SendDefaultKey(key) {
    Send, {%key%}
}
CtrlReplacement(key) {
    static keyFunctions := []
    If (!keyFunctions.HasKey(key)) {
        keyFunctions[key] := Func("SendDefaultKey").Bind(key)
    }
    func := keyFunctions[key]
    If (A_PriorHotkey == A_ThisHotkey && A_TimeSincePriorHotkey < keyDelay) {
        SetTimer, % func, Off
        Send, {Ctrl Down}{%key%}{Ctrl Up}
    } Else {
        RunFuncWithDelay(func)
    }
}
Setup() {
    ; Add/Remove affected characters here
    allkeys := ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","``","1","2","3","4","5","6","7","8","9","0","-","=","F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12","~","!","@","#","$","%","^","&","*","(",")","_","+","[","]","{","}","\","|",";",":","'","""",",","<",".",">","/","?","ENTER","DEL","SPACE","TAB","Numpad0","Numpad1","Numpad2","Numpad3","Numpad4","Numpad5","Numpad6","Numpad7","Numpad8","Numpad9","NumpadAdd","NumpadClear","NumpadDel","NumpadDiv","NumpadDot","NumpadDown","NumpadEnd","NumpadEnter","NumpadHome","NumpadIns","NumpadLeft","NumpadMult","NumpadRight","NumpadSub","NumpadUp"]
    ; The characters below will overwrite the above mappings
    ctrlkeys := ["a","b","c","e","f","g","h","i","k","q","r","s","t","v","w","x","z","F1","F2","F3","F4","]","SPACE"]
    For _,key in allkeys {
        keyfunc := Func("SendDefaultKey").Bind(key)
        delayfunc := Func("RunFuncWithDelay").Bind(keyfunc)
        Hotkey, $%key%, % delayfunc
    }
    For _,key in ctrlkeys {
        keyNum := Asc(key)
        func := Func("CtrlReplacement").Bind(key)
        Hotkey, $%key%, % func
    }
}
Setup()