为什么 Autohotkey 中的“ Keywait ”会导致在键入时替换两个字母?

问题描述

我有这个脚本:

#IfWinActive Oxford Advanced Learner's Dictionary
$m:: 
KeyWait,m,T0.25 
If (ErrorLevel) 
 {
    Click,210,563,10
    sleep,100
    Send,{Down}
    KeyWait,m 
 }
    Else
    {
        Send,m
    }        
return
 $i::
KeyWait,i,T0.25
If (ErrorLevel) {
    Loop 7
        Click,768,192,3
} else {
    Send,i
}
return

但是当我快速输入字母 mi 以输入“ mi ”时,它会输入“ im ”。但是当我输入它们的速度较慢时,不会出现问题。为什么会发生这种情况,我该如何解决这个问题?

解决方法

我认为来自 Threads page 的这句话在这里是相关的:

虽然 AutoHotkey 实际上并没有使用多线程,但它模拟了其中的一些行为:如果启动了第二个线程——例如在前一个线程仍在运行时按下另一个热键——当前线程将被中断(暂时暂停)以允许新线程成为当前线程。如果在第二个线程仍在运行时启动了第三个线程,则第二个线程和第一个线程都将处于休眠状态,依此类推。

当前线程结束时,最近中断的线程 将被恢复,依此类推,直到所有线程最终完成。

我相信当您在 m 之后键入 i 时,当 m 键等待仍在超时内时,它会快速地暂停该键等待并运行 i。

至于如何解决这个问题,只需在 m 热键中添加 Critical,注意这将使其在此热键完成之前不会运行其他热键,但它会排队:

#IfWinActive Oxford Advanced Learner's Dictionary
$m::
Critical
KeyWait,m,T0.25 
If (ErrorLevel) 
{
    Click,210,563,10
    sleep,100
    Send,{Down}
    KeyWait,m 
} else {
    Send,m
}        
return

$i::
KeyWait,i,T0.25
If (ErrorLevel) {
    Loop 7
        Click,768,192,3
} else {
    Send,i
}
return
,

我在 autohotkey 网站的论坛上找到了用户“Rohwedder”的以下代码 here

#IfWinActive Oxford Advanced Learner's Dictionary
~$m::
KeyWait,T0.25
If (ErrorLevel)
{
    Click,{Down}
}
return
~$i::
KeyWait,T0.25
If (ErrorLevel)
    Loop 7
        Click,3
return

它对我来说非常有效,但我通过以这种方式编写 keywait 意识到,当我按住 m 几秒钟时,与我的问题中的脚本不同,它首先输入一个“ m”,然后执行我为其定义的功能(单击并向下发送)。所以我的第一个表达式是尝试使用 critical 修复@Josh 在其他答案中建议的以前的代码。但我也遇到了一些问题!

最后我通过一点点调整使用了上面的代码:我添加了这个

   sleep,50
   send,{backspace}

在每个热键下方(if 内的第一行),因此结果是删除了通过立即按住一个键而产生的额外字母,然后它立即执行了我为其定义的功能。

这样问题就解决了!