长按 AHK 替代键

AHK Alternative key on long press

我有一个键盘,这些箭头(less/greater 比)字符作为 Y 和 X 上的备用键。

让我们关注此示例中的键 X。

默认情况下,替代字符 > 当然是通过 AltGr + X 触发的。

但我想通过简单地长按 X 来触发它,以加快速度并且不需要第二只手或手指。

到目前为止,我从其他帖子中得到以下信息:

$x::
    KeyWait, x, T0.2

    if (ErrorLevel)
        Send > ;long

    else {
        KeyWait, x, D T0.2

        if (ErrorLevel)
            Send x ;single
    }

    KeyWait, x
return

这基本可行,但有一个主要缺陷: 正常的单键按下现在需要太多时间来写入正常的 X 字符。

例如,如果您写得很快 "exchange" 这样的单词,您最终会得到 "echxange" 这样的单词,因为发送 X 需要太多时间。

那么如何修改这个脚本来解决这个问题呢?一旦注册了 {X Up},我的想法是发送一个普通的 X 并放弃整个脚本。所以在{X Up}之后他就不会再等了。

或者其他想法?

谢谢。

下面的代码似乎对我来说效果很好,但请注意,如果您连续输入许多 x,它可能会错误地替换 "x",但可能会错误地替换 "x",结果是这样的,"xxxx>xxx"。我将睡眠时间增加到 350 毫秒,以减少出现这种情况的可能性,但这是需要注意的事情,应该根据您的需要进行更改。

~x::
Sleep , 350
BlockInput , On
Send , % GetKeyState( "x" , P ) ? "{backspace}>" : ""
KeyWait , x , U
BlockInput , Off
Return

请注意,由于它发送退格键,如果在非键入环境中使用它,您可能会得到意想不到的结果,例如在浏览器中,如果您无法键入文本,它可能会返回到上一页。如果需要,可以通过使用 WinActive 或类似的东西过滤掉那些特定场景来缓解这种情况。

这是一个计算按键持续时间的解决方案,缺点是您总是必须释放按键才能获得所需的输入。这意味着您不能按住 x 来键入 xxxxxxxx。

$x::
    startTime := A_TickCount ;record the time the key was pressed
    KeyWait, x, U ;wait for the key to be released
    keypressDuration := A_TickCount-startTime ;calculate the duration the key was pressed down
    if (keypressDuration > 200) ;if the key was pressed down for more than 200ms send >
    {
        Send > 
    }
    else ;if the key was pressed down for less than 200ms send x
    {
         Send x 
    }

return

很简单,但需要 2 个单独的脚本。
首先 运行 这个脚本来阻止重复(我几乎可以肯定这就是你想要的)。

SendMode Input 

$x::
    send {x}
    keywait, x
    send {x up}
return

然后 运行 第二个脚本,执行以下逻辑:

SendMode Input 

dt := 30            ;  milliseconds time resolution
timeout := 1500 ;  timeout

loop 
{
    sleep %dt%                      ; sleep to reduce CPU usage
    p := getkeystate("x", "P")          ; getkeystate
    if (p = 1) {
        timer += dt
    }
    if (p = 0) {
        timer := 0
    }
    ; tooltip pressed:  %p%  timer: %timer%
    if (timer > timeout) {
        send {backspace}
        send {>}
        timer := 0              ; reset timer
    }
}

会正常输入x,1.5秒后会输入>,见timeout变量。诀窍是,在后一种情况下,它会删除最后一个 x 所以你只会得到 >.

我采纳了Yane提供的答案,并稍作改进。

不同点:Yane的回答会在你放开钥匙的时候发送钥匙。我的示例将在设定的时间后发送长按键。这样您就可以知道您的按键时间是否足够长。

$x::
    timeHasElapsed := 0
    SetTimer, SendAngleBracketRight, -200 ;if the key was pressed down for more than 200ms send > (negative value to make the timer run only once)
    KeyWait, x, U ;wait for the key to be released
    if (timeHasElapsed == 0) ;if the timer didn't go off disable the timer and send x
    {
        SetTimer, SendAngleBracketRight, OFF
        SendInput, x
    }
return

SendAngleBracketRight:
    SendInput, >
    timeHasElapsed := 1
return

我觉得更好的办法是发送key,然后如果长按超过设定的时间,就消除它,输入新的字符。这建立在 Animiles 代码上:

$x::
    Send, x ; initially send the character, if you then type another character the timer gets reset
    timeHasElapsed := 0
    SetTimer, SendAngleBracketRight, -200 ;if the key was pressed down for more than 200ms send > (negative value to make the timer run only once)
    KeyWait, x, U ;wait for the key to be released
    if (timeHasElapsed == 0) ;if the timer didn't go off disable the timer and send x
    SetTimer, SendAngleBracketRight, OFF
    timeHasElapsed := 1
return
SendAngleBracketRight:
    Send, {Backspace} ; eliminate the sent character
    Send, > ; send the new character
    timeHasElapsed := 1
return