使用 AHK 进行长按键检测

问题描述 投票:0回答:1

我正在使用以下最初由 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 + 其他键的任意组合并允许默认的系统行为。

感谢修改脚本的任何帮助

autohotkey long-press
1个回答
1
投票

这是正确答案,感谢“Rohwedder

Morse(Timeout = 200)
{
    Global Pattern := ""
    Win := WinExist("A")
    RegExMatch(Hotkey:=A_ThisHotkey, "\W$|\w*$", Key)
    CoordMode, Mouse, Screen
    MouseGetPos, X1, Y1, Win1
    
    While, !ErrorLevel {
        T := A_TickCount
        KeyWait %Key%
        Pattern .= A_TickCount-T > Timeout
        KeyWait %Key%,% "DT" Timeout/1500
        MouseGetPos, X2, Y2, Win2
        IF (Win key Hotkey Win1) <> (WinExist("A") A_PriorKey A_ThisHotkey Win2) Or 30 < (X2-X1)**2+(Y2-Y1)**2
            Exit
    } 
    Return Pattern
}
    
~LControl::
    Hotkey := SubStr(A_ThisHotkey, 2)
    Switch, Morse()
    {
        Case "0":
            MsgBox Ctrl short press
        Case "1":
            MsgBox Ctrl long press
        Case "00":
            MsgBox Ctrl double short press
        Case "01":
            MsgBox Ctrl short+long press
        Case "10":
            MsgBox Ctrl long+ short press
        Default:
            MsgBox Ctrl Press pattern: %Pattern%
    } 
    Return

这还可以处理 Ctrl 键与其他键的组合以及鼠标操作。 希望能帮助别人!

更新: 这是莫尔斯函数的另一个版本,仅检测 0, 1, 00, 01, 10, 11 模式,但速度更快:

DoubleMorse(Timeout = 200)
{
    Global Pattern := ""
    Win := WinExist("A")
    RegExMatch(Hotkey:=A_ThisHotkey, "\W$|\w*$", Key)
    CoordMode, Mouse, Screen
    MouseGetPos, X1, Y1, Win1
    
    if (!ErrorLevel) {
        T := A_TickCount
        KeyWait %Key%
        Pattern .= A_TickCount-T > Timeout
        KeyWait %Key%,% "DT" Timeout/1500
        MouseGetPos, X2, Y2, Win2
        IF (Win key Hotkey Win1) <> (WinExist("A") A_PriorKey A_ThisHotkey Win2) Or 30 < (X2-X1)**2+(Y2-Y1)**2
            Exit
    } 
    
    if (!ErrorLevel) {
        T := A_TickCount
        KeyWait %Key%
        Pattern .= A_TickCount-T > Timeout
    } 
    Return Pattern
}

如果您需要一些东西来快速操作 crezy,请使用仅检测 0、1(短按和长按)的功能:

SingleMorse(Timeout = 200)
{
    Global Pattern := ""
    Win := WinExist("A")
    RegExMatch(Hotkey:=A_ThisHotkey, "\W$|\w*$", Key)
    CoordMode, Mouse, Screen
    MouseGetPos, X1, Y1, Win1
    
    if (!ErrorLevel) {
        T := A_TickCount
        KeyWait %Key%
        Pattern .= A_TickCount-T > Timeout
        MouseGetPos, X2, Y2, Win2
        IF (Win key Hotkey Win1) <> (WinExist("A") A_PriorKey A_ThisHotkey Win2) Or 30 < (X2-X1)**2+(Y2-Y1)**2
            Exit
    } 

    Return Pattern
}
© www.soinside.com 2019 - 2024. All rights reserved.