在DirectX游戏中如何轮询鼠标与键盘并实现热键功能
解决DirectX游戏内CapsLock+鼠标左键热键失效问题
问题根源
DirectX游戏普遍采用Raw Input/DirectInput处理输入,会绕过Windows标准消息队列。你当前使用的pynput监听器依赖系统级消息钩子,当游戏窗口获取焦点时,这些钩子会被DirectX的输入机制屏蔽,导致无法捕获按键和鼠标事件。
解决方案:轮询输入状态替代监听回调
改用轮询方式实时检查CapsLock和鼠标左键的状态,结合pydirectinput发送按键(你已验证该库可在游戏内生效)。同时用独立线程处理轮询,避免阻塞UI界面。
修改后的代码
import customtkinter import pydirectinput import threading import time from pynput.mouse import Button, Controller as MouseController class Root(customtkinter.CTk): def __init__(self): super().__init__() # 窗口基础设置 self.title("Hotkey handler") customtkinter.set_appearance_mode("dark") self.wm_attributes('-alpha', 0.8) self.geometry('125x20+470+0') self.attributes("-topmost", 1) self.overrideredirect(1) self.label1 = customtkinter.CTkLabel( self, text="Hotkey status: ", fg_color="gray14") self.label1.pack(side=customtkinter.LEFT) self.label2 = customtkinter.CTkLabel( self, text="Ready", fg_color="gray14") self.label2.pack(side=customtkinter.RIGHT) self.running = True self.mouse = MouseController() # 启动输入状态轮询线程 self.poll_thread = threading.Thread(target=self.poll_inputs, daemon=True) self.poll_thread.start() def poll_inputs(self): last_triggered = False while self.running: # 读取CapsLock激活状态和鼠标左键按压状态 caps_lock_active = pydirectinput.keyDown('capslock') mouse_left_pressed = self.mouse.is_pressed(Button.left) if caps_lock_active and mouse_left_pressed: if not last_triggered: # 发送[按键 pydirectinput.press('[') self.label2.configure(text_color="red") last_triggered = True else: if last_triggered: # 根据CapsLock状态更新提示文字颜色 self.label2.configure(text_color="#DCE4EE" if not caps_lock_active else "green") last_triggered = False # 控制轮询频率,平衡响应速度与CPU占用 time.sleep(0.01) def destroy(self): self.running = False super().destroy() root = Root() root.mainloop()
关键改动说明
- 轮询机制:通过线程循环读取硬件级输入状态,不受DirectX消息屏蔽影响,替代原有的
pynput回调监听。 - CapsLock状态检查:使用
pydirectinput.keyDown('capslock')直接获取CapsLock的激活状态(此方法为状态查询,而非主动按下按键)。 - 鼠标状态读取:
pynput.mouse.Controller的is_pressed方法可在游戏内正常读取鼠标按键状态。 - 防重复触发:通过
last_triggered变量避免按住按键时重复发送[字符。
额外注意事项
- 程序需要以管理员权限运行,否则可能无法在部分全屏游戏中读取输入状态。
- 可调整
time.sleep(0.01)的值:数值越小响应越快,但CPU占用越高;数值越大则相反。 - 若游戏带有反作弊系统,此类输入工具可能被检测,使用前请确认游戏规则。
内容的提问来源于stack exchange,提问作者Ludo
相关产品推荐
相关产品推荐

