我自我回答这个问题,因为我已经看到它在互联网上问过,但几乎没有什么有用的答案,而且我找不到Stack Overflow的解决方案。
考虑这段代码,它简单地写了几行shell命令:
^0::
SetKeyDelay, 0, 0
myWindow = ahk_exe Notepad.exe
ControlSend, , set c=".cshrc-andrew.cheong"`n, %myWindow%
ControlSend, , set v=".vimrc-andrew.cheong"`n, %myWindow%
ControlSend, , foreach d ( /userhome/andrew.cheong /home/$USER /data/$USER )`n, %myWindow%
ControlSend, , if ( -e $d/$c ) source $d/$c`n, %myWindow%
ControlSend, , if ( -e $d/$v ) alias vim "vim -N -u $d/$v"`n, %myWindow%
ControlSend, , end`n, %myWindow%
Return
我将命令写入记事本,以表明它是不一个仅限于PuTTy或xterm等终端应用程序的问题。这很容易想到,因为这些应用程序有时会出现滞后行为。
特别是在使用SetKeyDelay, 0, 0
进行快速"输入时,"我得到了各种奇怪的行为,比如:
双引号替换为单引号。括号由9&0和0代替。美元符号由4&s代替。
set c=".cshrc-andrew.cheong'
set v=".vimrc-andrew.cheong"
foreach d ( /userhome/andrew.cheong /home/$USER /data/$USER )
if 9 -e 4d/4c 0 source 4d/4c
if ( -e $d/$v ) alias vim 'vim -n -u 4d/4v'
end
用下划线代替破折号。案件变更。
set c='.cshrc-andrew.cheong"
set v='.vimrc-andrew.cheong'
foreach d ( /userhome/andrew.cheong /home/4user /data/$USER )
if 9 -e 4d/$C ) source 4d/$c
if 9 _e $d/$v ) alias vim 'vim -N -u $d/$v"
end
期间被>'取代。更多案例变更。
set c=".cshrc-andrew.cheong"
set v=">VIMrc-andrew.cheong"
foreach d ( /userhome/andrew.cheong /home/$USER /data/$USER )
if 9 -e $d/$c ) source 4d/$c
if ( -e $d/$V ) alias vim "vim -N -u $d/$v"
end
显而易见,该问题与 Shift 修饰符有关,就好像它随机打开或关闭一样。
为什么会发生这种情况,我们该如何解决?
请注意,使用Send
及其变体时没有问题。问题特别出现在ControlSend
,这是将输入发送到特定控件或未聚焦窗口所需的。
答案 0 :(得分:1)
将其复制到您的脚本中(来自AutoHotkey论坛的用户RHCP):
pSendChars(string, control := "", WinTitle := "", WinText := "", ExcludeTitle := "", ExcludeText := "")
{
for k, char in StrSplit(string)
postmessage, WM_CHAR := 0x102, Asc(char),, %Control%, %WinTitle%, %WinText%, %ExcludeTitle%, %ExcludeText%
return
}
并像这样使用它:
^0::
myWindow = ahk_exe Notepad.exe
line .= "set c="".cshrc-acheong""`n"
line .= "set v="".vimrc-acheong""`n"
line .= "foreach d ( /userhome/andrew.cheong /home/cama /home/$USER )`n"
line .= " if ( -e $d/$c ) source $d/$c`n"
line .= " if ( -e $d/$v ) alias vim ""vim -N -u $d/$v""`n"
line .= "end`n"
pSendChars(line, "edit1", myWindow)
Return
就是这样。
请注意edit1
是其文本控件的记事本名称。将此脚本用于PuTTy时,我将其更改为空白字符串。使用AutoHotkey的WindowSpy程序找出你想要写入的控件。
之前已经出现过几次。只是为了添加Lexikos 写道,问题是由于controlSend使用这两个帖子 message和sendInput / sendEvent发送击键。这是必需的 因为有些程序无法正确解释击键,除非 发送的修饰键在逻辑上是关闭的(通过sendInput / Event发送)。
发送修饰键(除非明确说明,例如{shitft down}) 通过sendInput通过postMessage发送非修改器。密钥发送 通过postmessage直接发送到窗口,因此延迟较少 比其他键/消息。因此可以进行击键 消息不同步到达导致意外字符。在 在这种情况下,大写字母需要通过移位键发送 sendInput /活动。
除了使用keyDelays,您还可以尝试controlSetText和发布 WM_Char消息。如果您正在使用文本控件,我会 建议使用controlSetText。