我正在使用以下最初由 Laszlo 编写的 AutoHotkey 脚本来检测 Ctrl 键的单次、多次、短按和长按:
Morse(timeout = 150) { ;
tout := timeout/1000
key := RegExReplace(A_ThisHotKey,"[\*\~\$\#\+\!\^]")
Loop {
t := A_TickCount
KeyWait %key%
Pattern .= A_TickCount-t > timeout
KeyWait %key%,DT%tout%
If (ErrorLevel)
Return Pattern
}
}
~Ctrl::
p := Morse()
If (p = "0")
MsgBox Short press
Else If (p = "1")
MsgBox Long press
Else If (p = "00")
MsgBox Two short presses
Else If (p = "01")
MsgBox Short+Long presses
Else
MsgBox Press pattern %p%
Return
该脚本可以很好地区分短按和长按 Ctrl。但是,当我将 Ctrl 键与 z、c、v 等其他键一起使用时,我遇到了问题。 在这些情况下,脚本将这些组合检测为长按 Ctrl 键并显示“长按”消息框。 相反,我希望它忽略 Ctrl + 其他键的任意组合并允许默认的系统行为。
感谢修改脚本的任何帮助
正确答案是:
#Requires AutoHotkey v2.0
#SingleInstance Force
; Morse Function (To detect single, double, tripple or ... , short or long press)
Morse(Timeout := 200, PatternSequence := 10) ; Set patternSequence to 3, 2 for better performance. However, this will decrease the number of patterns detected.
{
Global Pattern := ""
Win := WinExist("A")
RegExMatch(Hotkey := A_ThisHotkey, "\W$|\w*$", &Key)
IsModifier := InStr(Hotkey, "Control") or InStr(Hotkey, "Alt") Or InStr(Hotkey, "Shift") Or InStr(Hotkey, "Win")
CoordMode("Mouse", "Screen")
MouseGetPos(&X1, &Y1, &Win1)
Counter := 0
Loop (PatternSequence) {
; Disabling Alt menu acceleration / Windows Start menu
If InStr(Hotkey, "Alt") Or InStr(Hotkey, "Win") ; Comment second condition if you need WIN key to open the start menu.
Send("{Blind}{vkE8}")
T := A_TickCount
ErrorLevel := !KeyWait(Key[0])
Pattern .= A_TickCount - T > Timeout
MouseGetPos(&X2, &Y2, &Win2)
; Skiping the operation for modifiers, if another key is pressed or mouse is moved.
IF (IsModifier) And (((Win Key[0] Hotkey Win1) != (WinExist("A") A_PriorKey A_ThisHotkey Win2)) Or (30 < (X2 - X1) ** 2 + (Y2 - Y1) ** 2))
Exit
; Skiping the last keywait to improve speed!
Counter += 1
If (Counter = PatternSequence)
return Pattern
; Waiting for the next key sequence to be pressed
ErrorLevel := !KeyWait(Key[0], "DT" Timeout / 1500)
If ErrorLevel
return Pattern
}
}
; Hotkey handler
~LControl::
~LAlt::
~LShift::
~LWin::
Tab::
Capslock::
{
hotkey := A_ThisHotkey
Patterm := Morse() ; Morse(, 2) ; If you only need the following patterns.
Switch Patterm
{
Case "0":
MsgBox(hotkey " " Patterm)
Case "1":
MsgBox(hotkey " " Patterm)
Case "00":
MsgBox(hotkey " " Patterm)
Case "01":
MsgBox(hotkey " " Patterm)
Case "10":
MsgBox(hotkey " " Patterm)
Case "11":
MsgBox(hotkey " " Patterm)
Default: ; Preferably comment these two lines after testing
MsgBox(hotkey " " Patterm)
}
Return
}
变更日志:
我使用了
Laszlo
编写的原始莫尔斯电码函数,它可以检测任意键的单次/多次、短按/长按。但它有一些问题,特别是修饰键。
在
Rohwedder
的大力帮助下,脚本被修改为检测组合键(例如Ctrl+z
)或鼠标移动(例如Ctrl+Mouse drag
)并让它们执行默认功能。
下一步,我改进了脚本以获得更好的性能。
最后,我解决了
Alt
键与禁用“Alt键加速”的冲突,以及Win
键与开始菜单的冲突。
用途:
对于不同的热键,您可以设置不同的超时时间,以及不同的模式序列。
例如,在实际情况中,我需要按一次 Shift 键(模式:0)来发送
Alt + Shift
来更改输入语言。
但我注意到在快速打字的情况下切换语言时会出现延迟。
因此,我决定使用以下参数调用 Morse 函数:Pattern := Morse(400, 1)
。
这消除了滞后,因为它只经历一次循环。 它还解决了我的另一个问题,即短按和长按 Shift 键冲突,因为检测长按的超时时间增加。 缺点是只有两种模式可供使用:短按和长按!
参考资料: