使用 AutoHotKey 防止物理按键与发送的键冲突
Preventing physical key presses from conflicting with sent keys using AutoHotKey
我想使用 autohotkey 定义一个快捷方式,自动导航到 Word 功能区菜单中的单元格宽度文本框(即发送键 Alt,j,l,w while in Word).
我对脚本的最初尝试引入了一个问题,即在脚本发送键之前,物理按键的 Up
操作尚未完成,导致脚本失败。
虽然我有一个解决方法(使用 sleep 250
,如下所示),但我想了解是否有更优雅的解决方案 - 例如此值是通过反复试验选择的,此解决方法可能在另一台机器上失败,或者如果我的笔记本电脑今天运行不佳。
基本上,我想找到一个解决方案,避免对等待时间进行硬编码。
有什么建议吗?
问题
在我的初始脚本中,我尝试定义热键 Alt+Shift+p在 Word 中,发送 Alt、j、l、w 按顺序。这失败了,而是将文本 "jlw" 输入到活动的 table 单元格中。
这是因为对于物理按下的键(在下面的评论中用 #
标记),Up
操作尚未 运行 当脚本已经开始发送键时(指示$
)。这会打乱发送顺序 Alt,j,l,w 所以它失败了。
另请注意,标有 ?
的事件可能是失败操作的副产品。
脚本
; Jump to table cell width entry when Alt+Shift+p pressed in Word only
#IfWinActive, ahk_exe WINWORD.EXE
!+p::
Send, {RAlt down}{RAlt up}jlw
Return
密钥历史记录
VK SC Type Up/Dn Elapsed Key Comment
-------------------------------------------------------------------------------------------------------------
A4 038 d 1.03 LAlt #
A0 02A d 0.14 LShift #
50 019 h d 0.13 p #, h=Hook Hotkey
A5 138 i d 0.02 RAlt $
A5 138 i u 0.00 RAlt $
11 01D i d 0.00 Control ?
11 01D i u 0.00 Control ?
A4 038 i u 0.00 LAlt #
A0 02A i u 0.00 LShift #
4A 024 i d 0.00 j $
4A 024 i u 0.00 j $
4C 026 i d 0.00 l $
4C 026 i u 0.00 l $
57 011 i d 0.00 w $
57 011 i u 0.00 w $
11 01D i d 0.00 Control ?
A4 038 i d 0.00 LAlt ?
11 01D i u 0.00 Control ?
A0 02A i d 0.00 LShift ?
50 019 s u 0.08 p #
A0 02A u 0.25 LShift ?
A4 038 u 0.00 LAlt ?
解决方法
通过添加 sleep 250
语句,热键和发送键按预期顺序 运行。请注意,没有其他键被触发(?
没有指示)。
脚本
; Jump to table cell width entry when Alt+Shift+p pressed in Word only
#IfWinActive, ahk_exe WINWORD.EXE
!+p::
Sleep 250
Send, {RAlt down}{RAlt up}jlw
Return
密钥历史记录
VK SC Type Up/Dn Elapsed Key Comment
-------------------------------------------------------------------------------------------------------------
A4 038 d 0.39 LAlt #
A0 02A d 0.20 LShift #
50 019 h d 0.20 p #, h=Hook Hotkey
50 019 s u 0.11 p #
A0 02A u 0.11 LShift #
A4 038 u 0.00 LAlt #
A5 138 i d 0.03 RAlt $
A5 138 i u 0.00 RAlt $
4A 024 i d 0.00 j $
4A 024 i u 0.00 j $
4C 026 i d 0.00 l $
4C 026 i u 0.00 l $
57 011 i d 0.00 w $
57 011 i u 0.00 w $, SUCCESS!
如果目标window没有可靠地接收到击键,您可以尝试通过SetKeyDelay的第二个参数在发送命令中增加按键持续时间,例如
!+p::
SetKeyDelay, 10, 10
Send, {RAlt down}{RAlt up}jlw
Return
不确定您为什么使用正确的 alt,甚至认为这不应该起作用。只需使用 "Alt"。而且我认为您的热键对此不是很好。 Word 与输入混淆。
但我认为也许这样做会奏效
!+p up:: ;up means it'll run once u release p, might help a bit
SetKeyDelay, 500, 10 ;good amount of delay, can probably do with less
Send, {Shift Up}{Alt Up}{Alt}jlw ;send shift and alt up first
Return
现在有一个更好的选择,用 Word ComObject. Usage of VBA 自动化它,因为这是 正常 和预期的方式,但你可以 AHK(或任何其他语言) 也一样。
这是更改第一个 table 的第一个单元格宽度的快速 AHK 示例:
Word := ComObjActive("Word.Application")
Word.ActiveDocument.Tables(1).Cell(1, 1).Width := 500
当然,这不是解决此问题的好方法,我相信您可以以某种方式引用活动 table 和活动单元格,我只是快速阅读文档并写下了它。我自己实际上从来没有在实践中使用过这些东西。
我使用 KeyWait
找到了一个更优雅的解决方案。与我之前的解决方法脚本相比,我认为这更优雅,因为它不需要硬编码等待时间。这只是在脚本继续之前等待按下的键出现,防止任何冲突:
脚本
#IfWinActive, ahk_exe WINWORD.EXE
!+p::
KeyWait Alt
KeyWait Shift
KeyWait p
Send, {Alt Down}{Alt Up}jlw
Return
密钥历史记录
VK SC Type Up/Dn Elapsed Key Comment using previous notation
-------------------------------------------------------------------------------------------------------------
A4 038 d 0.63 LAlt #
A0 02A d 0.11 LShift #
50 019 h d 0.11 p #
50 019 s u 0.06 p #
A0 02A u 0.19 LShift #
A4 038 u 0.00 LAlt #
12 038 i d 0.01 Alt $
12 038 i u 0.00 Alt $
4A 024 i d 0.00 j $
4A 024 i u 0.00 j $
4C 026 i d 0.00 l $
4C 026 i u 0.00 l $
57 011 i d 0.00 w $
57 011 i u 0.00 w $
有趣的是,修改为使用 Send, !jlw
的上述脚本有效(即导航到“单元格宽度”框),但发送的键按如下顺序出现。我不会使用它,只是为了避免这种乱序发生的任何意外后果。
VK SC Type Up/Dn Elapsed Key Comment
-------------------------------------------------------------------------------------------------------------
A4 038 d 1.17 LAlt
A0 02A d 0.11 LShift
50 019 h d 0.14 p
50 019 s u 0.09 p
A0 02A u 0.16 LShift
A4 038 u 0.00 LAlt
A4 038 i d 0.02 LAlt <--
4A 024 i d 0.00 j
4A 024 i u 0.00 j
A4 038 i u 0.00 LAlt <--
4C 026 i d 0.00 l
4C 026 i u 0.00 l
57 011 i d 0.00 w
57 011 i u 0.00 w
我想使用 autohotkey 定义一个快捷方式,自动导航到 Word 功能区菜单中的单元格宽度文本框(即发送键 Alt,j,l,w while in Word).
我对脚本的最初尝试引入了一个问题,即在脚本发送键之前,物理按键的 Up
操作尚未完成,导致脚本失败。
虽然我有一个解决方法(使用 sleep 250
,如下所示),但我想了解是否有更优雅的解决方案 - 例如此值是通过反复试验选择的,此解决方法可能在另一台机器上失败,或者如果我的笔记本电脑今天运行不佳。
基本上,我想找到一个解决方案,避免对等待时间进行硬编码。
有什么建议吗?
问题
在我的初始脚本中,我尝试定义热键 Alt+Shift+p在 Word 中,发送 Alt、j、l、w 按顺序。这失败了,而是将文本 "jlw" 输入到活动的 table 单元格中。
这是因为对于物理按下的键(在下面的评论中用 #
标记),Up
操作尚未 运行 当脚本已经开始发送键时(指示$
)。这会打乱发送顺序 Alt,j,l,w 所以它失败了。
另请注意,标有 ?
的事件可能是失败操作的副产品。
脚本
; Jump to table cell width entry when Alt+Shift+p pressed in Word only
#IfWinActive, ahk_exe WINWORD.EXE
!+p::
Send, {RAlt down}{RAlt up}jlw
Return
密钥历史记录
VK SC Type Up/Dn Elapsed Key Comment
-------------------------------------------------------------------------------------------------------------
A4 038 d 1.03 LAlt #
A0 02A d 0.14 LShift #
50 019 h d 0.13 p #, h=Hook Hotkey
A5 138 i d 0.02 RAlt $
A5 138 i u 0.00 RAlt $
11 01D i d 0.00 Control ?
11 01D i u 0.00 Control ?
A4 038 i u 0.00 LAlt #
A0 02A i u 0.00 LShift #
4A 024 i d 0.00 j $
4A 024 i u 0.00 j $
4C 026 i d 0.00 l $
4C 026 i u 0.00 l $
57 011 i d 0.00 w $
57 011 i u 0.00 w $
11 01D i d 0.00 Control ?
A4 038 i d 0.00 LAlt ?
11 01D i u 0.00 Control ?
A0 02A i d 0.00 LShift ?
50 019 s u 0.08 p #
A0 02A u 0.25 LShift ?
A4 038 u 0.00 LAlt ?
解决方法
通过添加 sleep 250
语句,热键和发送键按预期顺序 运行。请注意,没有其他键被触发(?
没有指示)。
脚本
; Jump to table cell width entry when Alt+Shift+p pressed in Word only
#IfWinActive, ahk_exe WINWORD.EXE
!+p::
Sleep 250
Send, {RAlt down}{RAlt up}jlw
Return
密钥历史记录
VK SC Type Up/Dn Elapsed Key Comment
-------------------------------------------------------------------------------------------------------------
A4 038 d 0.39 LAlt #
A0 02A d 0.20 LShift #
50 019 h d 0.20 p #, h=Hook Hotkey
50 019 s u 0.11 p #
A0 02A u 0.11 LShift #
A4 038 u 0.00 LAlt #
A5 138 i d 0.03 RAlt $
A5 138 i u 0.00 RAlt $
4A 024 i d 0.00 j $
4A 024 i u 0.00 j $
4C 026 i d 0.00 l $
4C 026 i u 0.00 l $
57 011 i d 0.00 w $
57 011 i u 0.00 w $, SUCCESS!
如果目标window没有可靠地接收到击键,您可以尝试通过SetKeyDelay的第二个参数在发送命令中增加按键持续时间,例如
!+p::
SetKeyDelay, 10, 10
Send, {RAlt down}{RAlt up}jlw
Return
不确定您为什么使用正确的 alt,甚至认为这不应该起作用。只需使用 "Alt"。而且我认为您的热键对此不是很好。 Word 与输入混淆。
但我认为也许这样做会奏效
!+p up:: ;up means it'll run once u release p, might help a bit
SetKeyDelay, 500, 10 ;good amount of delay, can probably do with less
Send, {Shift Up}{Alt Up}{Alt}jlw ;send shift and alt up first
Return
现在有一个更好的选择,用 Word ComObject. Usage of VBA 自动化它,因为这是 正常 和预期的方式,但你可以 AHK(或任何其他语言) 也一样。
这是更改第一个 table 的第一个单元格宽度的快速 AHK 示例:
Word := ComObjActive("Word.Application")
Word.ActiveDocument.Tables(1).Cell(1, 1).Width := 500
当然,这不是解决此问题的好方法,我相信您可以以某种方式引用活动 table 和活动单元格,我只是快速阅读文档并写下了它。我自己实际上从来没有在实践中使用过这些东西。
我使用 KeyWait
找到了一个更优雅的解决方案。与我之前的解决方法脚本相比,我认为这更优雅,因为它不需要硬编码等待时间。这只是在脚本继续之前等待按下的键出现,防止任何冲突:
脚本
#IfWinActive, ahk_exe WINWORD.EXE
!+p::
KeyWait Alt
KeyWait Shift
KeyWait p
Send, {Alt Down}{Alt Up}jlw
Return
密钥历史记录
VK SC Type Up/Dn Elapsed Key Comment using previous notation
-------------------------------------------------------------------------------------------------------------
A4 038 d 0.63 LAlt #
A0 02A d 0.11 LShift #
50 019 h d 0.11 p #
50 019 s u 0.06 p #
A0 02A u 0.19 LShift #
A4 038 u 0.00 LAlt #
12 038 i d 0.01 Alt $
12 038 i u 0.00 Alt $
4A 024 i d 0.00 j $
4A 024 i u 0.00 j $
4C 026 i d 0.00 l $
4C 026 i u 0.00 l $
57 011 i d 0.00 w $
57 011 i u 0.00 w $
有趣的是,修改为使用 Send, !jlw
的上述脚本有效(即导航到“单元格宽度”框),但发送的键按如下顺序出现。我不会使用它,只是为了避免这种乱序发生的任何意外后果。
VK SC Type Up/Dn Elapsed Key Comment
-------------------------------------------------------------------------------------------------------------
A4 038 d 1.17 LAlt
A0 02A d 0.11 LShift
50 019 h d 0.14 p
50 019 s u 0.09 p
A0 02A u 0.16 LShift
A4 038 u 0.00 LAlt
A4 038 i d 0.02 LAlt <--
4A 024 i d 0.00 j
4A 024 i u 0.00 j
A4 038 i u 0.00 LAlt <--
4C 026 i d 0.00 l
4C 026 i u 0.00 l
57 011 i d 0.00 w
57 011 i u 0.00 w