153 lines
4.7 KiB
Python
153 lines
4.7 KiB
Python
|
|
import os
|
|||
|
|
import sys
|
|||
|
|
import ctypes
|
|||
|
|
from ctypes import *
|
|||
|
|
import time
|
|||
|
|
import win32com.client
|
|||
|
|
import pythoncom
|
|||
|
|
|
|||
|
|
class HardwareController:
|
|||
|
|
"""
|
|||
|
|
接入 wyhkm.dll 硬件盒子的 COM 接口封装类。
|
|||
|
|
经过实测验证:Index 0 配合 SetMode(2, 1) 可同时支持键盘与鼠标。
|
|||
|
|
"""
|
|||
|
|
_instance = None
|
|||
|
|
_wyhkm = None
|
|||
|
|
|
|||
|
|
def __new__(cls, *args, **kwargs):
|
|||
|
|
if not cls._instance:
|
|||
|
|
cls._instance = super(HardwareController, cls).__new__(cls)
|
|||
|
|
return cls._instance
|
|||
|
|
|
|||
|
|
def __init__(self, dll_path="ddl/wyhkm.dll"):
|
|||
|
|
if self._wyhkm:
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
self.dll_path = os.path.abspath(dll_path)
|
|||
|
|
if not os.path.exists(self.dll_path):
|
|||
|
|
print(f">>> [硬件控制] 错误:找不到 DLL 文件 {self.dll_path}")
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
# 1. 进程内注册 (标准 64 位注册方式)
|
|||
|
|
hkmdll = windll.LoadLibrary(self.dll_path)
|
|||
|
|
hkmdll.DllInstall.argtypes = (c_long, c_longlong)
|
|||
|
|
|
|||
|
|
if hkmdll.DllInstall(1, 2) < 0:
|
|||
|
|
print(">>> [硬件控制] 注册失败!")
|
|||
|
|
return
|
|||
|
|
else:
|
|||
|
|
print(">>> [硬件控制] 进程内注册 wyhkm.dll 成功")
|
|||
|
|
|
|||
|
|
# 2. 创建对象
|
|||
|
|
pythoncom.CoInitialize()
|
|||
|
|
try:
|
|||
|
|
self._wyhkm = win32com.client.Dispatch("wyp.hkm")
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f">>> [硬件控制] 创建对象失败: {e}")
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
# 3. 查找并打开设备 (Index 0 已验证支持键盘鼠标)
|
|||
|
|
dev_id = self._wyhkm.SearchDevice(0x2612, 0x1701, 0)
|
|||
|
|
if dev_id == -1:
|
|||
|
|
print(">>> [硬件控制] 未找到无涯键鼠盒子 (Index 0)")
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
if not self._wyhkm.Open(dev_id, 0):
|
|||
|
|
print(">>> [硬件控制] 打开设备失败")
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
# 4. 关键初始化设置 (实测鼠标移动必须开启模式 2, 1)
|
|||
|
|
# 开启键盘增强模拟
|
|||
|
|
self._wyhkm.SetMode(1, 1)
|
|||
|
|
# 开启鼠标仿真移动 (解决鼠标不动的问题)
|
|||
|
|
self._wyhkm.SetMode(2, 1)
|
|||
|
|
|
|||
|
|
# 设置推荐的按键/鼠标间隔 (与 test_hw.py 一致,30-50ms 更稳定)
|
|||
|
|
self._wyhkm.SetKeyInterval(30, 50)
|
|||
|
|
self._wyhkm.SetMouseInterval(30, 50)
|
|||
|
|
|
|||
|
|
print(f">>> [硬件控制] 成功打开设备并完成初始化配置")
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f">>> [硬件控制] 初始化异常: {e}")
|
|||
|
|
self._wyhkm = None
|
|||
|
|
|
|||
|
|
def is_available(self):
|
|||
|
|
if not self._wyhkm:
|
|||
|
|
return False
|
|||
|
|
try:
|
|||
|
|
# 修正:IsOpen 需要参数 (0:全模式, 1:键盘, 2:鼠标)
|
|||
|
|
# 之前漏传参数会导致 COM 报错,进而导致 key_down 等所有操作被 skip
|
|||
|
|
return self._wyhkm.IsOpen(0)
|
|||
|
|
except:
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
def delay_rnd(self, min_ms, max_ms):
|
|||
|
|
"""随机延时"""
|
|||
|
|
if self.is_available():
|
|||
|
|
try: self._wyhkm.DelayRnd(int(min_ms), int(max_ms))
|
|||
|
|
except: pass
|
|||
|
|
|
|||
|
|
# --- 键盘操作 (均使用大写字符串) ---
|
|||
|
|
|
|||
|
|
def key_down(self, key_str):
|
|||
|
|
if self.is_available():
|
|||
|
|
try: self._wyhkm.KeyDown(str(key_str).upper())
|
|||
|
|
except: pass
|
|||
|
|
|
|||
|
|
def key_up(self, key_str):
|
|||
|
|
if self.is_available():
|
|||
|
|
try: self._wyhkm.KeyUp(str(key_str).upper())
|
|||
|
|
except: pass
|
|||
|
|
|
|||
|
|
def key_press(self, key_str):
|
|||
|
|
if self.is_available():
|
|||
|
|
try: self._wyhkm.KeyPress(str(key_str).upper())
|
|||
|
|
except: pass
|
|||
|
|
|
|||
|
|
# 兼容性别名
|
|||
|
|
def keyDown(self, key_str): self.key_down(key_str)
|
|||
|
|
def keyUp(self, key_str): self.key_up(key_str)
|
|||
|
|
def press(self, key_str): self.key_press(key_str)
|
|||
|
|
|
|||
|
|
# --- 鼠标操作 ---
|
|||
|
|
|
|||
|
|
def move_to(self, x, y):
|
|||
|
|
"""绝对移动"""
|
|||
|
|
if self.is_available():
|
|||
|
|
try: self._wyhkm.MoveTo(int(x), int(y))
|
|||
|
|
except: pass
|
|||
|
|
|
|||
|
|
def move_r(self, dx, dy):
|
|||
|
|
"""相对移动"""
|
|||
|
|
if self.is_available():
|
|||
|
|
try: self._wyhkm.MoveR(int(dx), int(dy))
|
|||
|
|
except: pass
|
|||
|
|
|
|||
|
|
def MoveR(self, dx, dy): # 兼容写法
|
|||
|
|
self.move_r(dx, dy)
|
|||
|
|
|
|||
|
|
def left_click(self):
|
|||
|
|
if self.is_available():
|
|||
|
|
try: self._wyhkm.LeftClick()
|
|||
|
|
except: pass
|
|||
|
|
|
|||
|
|
def right_click(self):
|
|||
|
|
if self.is_available():
|
|||
|
|
try: self._wyhkm.RightClick()
|
|||
|
|
except: pass
|
|||
|
|
|
|||
|
|
def left_down(self):
|
|||
|
|
if self.is_available():
|
|||
|
|
try: self._wyhkm.LeftDown()
|
|||
|
|
except: pass
|
|||
|
|
|
|||
|
|
def left_up(self):
|
|||
|
|
if self.is_available():
|
|||
|
|
try: self._wyhkm.LeftUp()
|
|||
|
|
except: pass
|
|||
|
|
|
|||
|
|
# 全局实例
|
|||
|
|
hw_ctrl = HardwareController()
|