AutoHotkey中如何让A_ThisHotkey与A_PriorHotkey捕获未声明为热键的键鼠按键
AutoHotkey中如何让A_ThisHotkey与A_PriorHotkey捕获未声明为热键的键鼠按键
我完全理解你的痛点——靠A_ThisHotkey和A_PriorHotkey确实没法实现你的需求,因为这两个变量天生就是为脚本里手动声明的热键服务的,只有触发了脚本内定义的热键,它们才会更新值。要捕获所有未声明的键鼠按键,我们得换个思路:用全局钩子来监听所有按键事件,自己维护最近按键的记录,而不是依赖AutoHotkey自带的热键变量。
下面是具体的实现方案,不需要把所有键都声明为热键,就能完美实现你的需求:
#SingleInstance Force #Persistent #NoEnv #Warn, All, OutputDebug ; 启用全局键盘和鼠标钩子,让脚本能捕获所有键鼠操作 InstallKeybdHook InstallMouseHook ; 自定义变量:记录最近按下的按键/鼠标键 lastPressedKey := "" ; 标记Ctrl是否处于按下状态 ctrlIsDown := false ; 监听普通按键按下(WM_KEYDOWN 消息) OnMessage(0x0100, "RecordLastKey") ; 监听系统级按键按下(比如Alt组合键,WM_SYSKEYDOWN 消息) OnMessage(0x0104, "RecordLastKey") ; 监听鼠标左键按下(WM_LBUTTONDOWN 消息) OnMessage(0x0201, "RecordLastMouseKey") ; 可按需添加其他鼠标按键监听:右键是0x0204,中键是0x0207 ; OnMessage(0x0204, "RecordLastMouseKey") ; OnMessage(0x0207, "RecordLastMouseKey") ; 处理键盘按键记录 RecordLastKey(wParam, lParam) { global lastPressedKey ; 将虚拟键码转换为易读的按键名称 keyName := GetKeyName("VK" . Format("{:X}", wParam)) lastPressedKey := keyName } ; 处理鼠标按键记录 RecordLastMouseKey(wParam, lParam) { global lastPressedKey ; 根据消息类型判断鼠标键,这里以左键为例 lastPressedKey := "LButton" ; 右键可改为"RButton",中键改为"MButton" } ; 监听Ctrl按下事件,标记状态并更新最近按键 ~LCtrl:: ctrlIsDown := true lastPressedKey := "LCtrl" Return ; 监听Ctrl释放事件,判断期间是否有其他按键按下 ~LCtrl Up:: ctrlIsDown := false if (lastPressedKey = "LCtrl") { ToolTip, 最近按下的键是Ctrl,期间没有其他按键触发 } else { ToolTip, 最近按下的键是「%lastPressedKey%」,是在Ctrl按住时按下的 } ; 5秒后自动关闭提示框 SetTimer, ToolTip, -5000 Return
代码说明:
- 全局钩子启用:通过
InstallKeybdHook和InstallMouseHook让脚本获得捕获所有键鼠操作的权限,这是实现全局监听的核心。 - 消息监听:用
OnMessage监听系统级的按键/鼠标按下消息,不管按键有没有被声明为热键,只要按下就会触发对应的处理函数。 - 自定义记录变量:用
lastPressedKey手动记录最近的按键,替代A_ThisHotkey的作用,这样所有键鼠操作都会被记录下来。 - Ctrl状态判断:通过
ctrlIsDown标记Ctrl的按下状态,释放时对比lastPressedKey的值,就能知道期间是否有其他按键被触发。
这个方案不需要声明所有按键为热键,也不会影响原按键的正常功能(~符号保证了热键不会阻塞原按键的系统行为),完全符合你的需求。
备注:内容来源于stack exchange,提问作者Ralf_Reddings
相关产品推荐
相关产品推荐

