https://github.com/evilC/AutoHotInterception

自动热拦截

AutoHotInterception (AHI) 允许您执行 AutoHotkey 代码以响应来自特定键盘或鼠标的事件,同时(可选)阻止本机功能(即阻止 Windows 看到该键盘或鼠标事件)。
换句话说,您可以使用第二个(或第三个或第四个…)键盘上的一个键来触发 AHK 代码,而应用程序不会看到该键。您可以在多个键盘上使用相同的键来执行单个操作。
支持键盘键、鼠标按钮和鼠标移动(相对和绝对模式)。
AHI 使用 Francisco Lopez 的 Interception 驱动程序

获得帮助

AHK 论坛上的 AHI 讨论主题

不和谐频道


警告

使用此代码时要小心。因为 Interception 是一个驱动程序,并且位于适当的窗口下方,所以 Interception 的阻塞非常深入,甚至可以阻止 CTRL+ALT+DEL 等。因此,完全可以锁定所有输入,或者至少让生活变得更美好一点难的。
一般来说,最坏的情况需要使用重置按钮。
例如,使用block启用的订阅模式将完全阻止该键在该键盘上工作。因此,如果您Ctrl在唯一的键盘上进行屏蔽,那么您只是屏蔽了 CTRL+ALT+DEL。
最好的保险政策是手边有另一个键盘或鼠标,你不会阻止。
小心使用此代码在启动时运行脚本。了解如何在 Windows 中进入“安全模式”并禁用脚本的启动。了解紧急键盘操作的鼠标替代方案(右键单击任务管理器的时钟!)
正如他们所说 -强大的力量带来了巨大的责任
如果这一切让您感到害怕并且您并不真正理解它,那么 TL/DR 是您可能应该坚持“上下文模式”,它更安全。


设备 ID/VID PID 等

拦截通过 ID 识别唯一设备。这是 1..20 中的数字。
设备 1-10 始终是键盘
设备 11-20 始终是鼠标
此 ID 方案对于 Interception 来说是完全独特的,并且 ID 可能会随着您插入/拔出设备等而改变。
在 PC 上,设备通常由 VendorID (VID) 和 ProductID ( PID)。这些是制造时嵌入硬件的标识符,对于相同品牌/型号的所有设备都是相同的。
大多数 AHI 功能(例如订阅密钥等)使用拦截 ID,因此提供了一些方便的功能,以允许您在给定 VID / PID 的情况下找到设备的(当前)拦截 ID。
如果您不确定设备的 VID / PID 是什么(或者即使 Interception 可以看到),您可以使用包含的 Monitor 脚本来查找它。
您需要知道至少一个设备的 VID / PID 才能对 AHI 进行任何操作。

监控应用

这个方便的工具允许您检查 AHI 是否正常工作,还可以找到您设备的 VID/PID 或 DeviceHandle。
您可以使用方便的“复制”按钮将设备的 VID/PID 或 DeviceHandle 复制到剪贴板。
使用监控应用程序时,不要一次勾选所有设备,如果它崩溃了,它会锁定所有设备。相反,一次勾选一个,看看它是否是您的设备。
多键盘开发 - 图1


已知的问题

如果您拔下/重新插入设备,或进入休眠和恢复,设备的拦截 ID 将增加 1。
如果设备的 ID 超过 10(对于键盘)或 20(对于鼠标),设备将完全在下次重新启动之前停止运行- 不仅在 AutoHotInterception 中,在 Windows 中也是如此。
我无法解决此问题,这是拦截驱动程序的限制


设置

  1. 下载并安装拦截驱动程序
    请注意,您必须install-interception.exe在管理员命令提示符下运行(不要双击它) - 一旦您这样做,它将指示您执行install-interception.exe /install以实际执行安装。
    这是一个显示该过程的GIF:

  2. 发布页面下载 AHI 版本并将其解压缩到文件夹中。
    不要使用主页上的“克隆或下载”链接。
    这是(至少在最初)您将从中运行脚本的文件夹。
    它包含许多示例.ahk脚本和一个lib文件夹,其中包含所有 AHI 库。

  3. 在 Interception 安装程序 zip 中,有一个library包含x86和文件夹的x64文件夹。
    将这两个文件夹复制到您在步骤 (3) 中创建的 AHIlib文件夹中 - 文件夹结构最终应如下所示:

AHI Root Folder Monitor.ahk etc… Lib AutoHotInterception.ahk AutoHotInterception.dll CLR.ahk Unblocker.ps1 etc.. x86 interception.dll x64 interception.dll

  1. 右键单击Unblocker.ps1lib 文件夹并选择Run as Admin.
    这是因为下载的 DLL 经常被阻止并且无法工作。
    这可以通过右键单击 DLL、选择属性并选中“块”框(如果存在)来手动完成。
  2. 编辑示例重映射脚本之一,将 VID/PID 替换为您的设备(使用 Monitor 应用程序找到它)并运行它以确保其正常工作。
  3. (可选)lib文件夹的内容实际上可以放在 AutoHotkey lib 文件夹之一中(例如My Documents\AutoHotkey\lib- 如果它不存在则创建它),并且#include示例脚本的行更改为#include ,以使您的 AHI 脚本可以在任何文件夹,而不是每个都需要它自己的库文件副本。

用法

初始化库

包括图书馆
#Persistent ; (Interception hotkeys do not stop AHK from exiting, so use this) #include Lib\AutoHotInterception.ahk
初始化库
global AHI := new AutoHotInterception()
注意
该AHI变量是一个 AHK 类,可以轻松地与 AutoHotInterception DLL 交互(然后它本身与 Interception dll 交互)。例如,它进行换GetDeviceList()行以使其返回一个正常的 AHK 数组。大多数时候你不需要它。
对于高级用户,如果您希望直接与 AHI DLL 通信(例如,为了获得最佳性能),您可以调用AHI.Instance而不是AHI大多数函数(例如,使用 发送合成输入时SendMouseMove)。
AHI := new AutoHotInterception() AHI.Instance.SendMouseMove(…)

杂项命令

设置状态

SetState(true|false)
打开或关闭所有订阅(开始)
在哪里true打开,在哪里false关闭。
例如AHI.SetState(false)

查找设备 ID

USB 设备

在大多数情况下,您需要将脚本硬连接到特定的 VID/PID - 在这种情况下,请使用以下方法之一。
对于所有这些方法,如果您有多个相同的 VID/PID 设备,您可以指定一个instance(从 1 开始)。

获取设备 ID

AHI.GetDeviceId(, , [,] )
如果您想找到鼠标或键盘,在isMouse哪里。 例如 ,查找具有 VID 0x04F2 和 PID 0x0112 的键盘truefalse
AHI.GetDeviceId(false, 0x04F2, 0x0112)

获取键盘 ID

AHI.GetKeyboardId(, [,] )

获取鼠标 ID

AHI.GetMouseId(, [,] )

PS/2 和其他 Legacy 设备(也适用于笔记本电脑)

某些设备(例如具有 PS/2 接口的旧机器或某些笔记本电脑)可能不使用 USB,因此这些设备没有 VID 和 PID。
在这种情况下,使用监控应用程序(或GetDeviceList())找出您设备的“手柄”,并从中获取它的 ID。

GetDeviceIdFromHandle

AHI.GetDeviceIdFromHandle(, [,] )
这与上面的工作方式相同GetDeviceId,除了你传递一个包含句柄的字符串。
例如AHI.GetDeviceIdFromHandle(false, “ACPI\PNP0303”) 找到带手柄的键盘ACPI\PNP0303

GetKeyboardIdFromHandle

AHI.GetKeyboardIdFromHandle( [,] )

GetMouseIdFromHandle

AHI.GetMouseIdFromHandle( [,] )

获取设备列表

如果您想获取所有可用设备的列表,可以调用AHI.GetDeviceList(),它将返回一个DeviceInfo对象数组,每个对象具有以下属性:
Id isMouse Vid Pid Handle

输入检测

AHI 有两种输入检测模式——上下文模式订阅模式,两者可以同时使用。

上下文模式

上下文模式之所以如此命名,是因为它利用了 AutoHotkey 的Context Sensitive Hotkeys
因此,此模式仅支持键盘键和鼠标按钮。不支持鼠标移动。
在上下文模式下,您创建一个上下文管理器对象,它为您打开/关闭一组 AHK 热键。
您将热键包装在由经理控制的#if 块中。
为键盘或鼠标创建一个上下文管理器,将设备的拦截 ID 传递给它。
然后创建你的热键,包裹在一个#if检查.IsActive你的上下文管理器属性的块中
(完整的工作脚本)
#include Lib\AutoHotInterception.ahk keyboard1Id := AHI.GetKeyboardId(0x04F2, 0x0112) cm1 := AHI.CreateContextManager(keyboard1Id) #if cm1.IsActive ; Start the #if block ::aaa::JACKPOT 1:: ToolTip % “KEY DOWN EVENT @ “ A_TickCount return 1 up:: ToolTip % “KEY UP EVENT @ “ A_TickCount return #if ; Close the #if block
您可以使用删除上下文管理器AHI.RemoveContextManager(keyboard1Id)

订阅模式

在订阅模式下,你完全绕过了 AHK 的热键系统,拦截通过回调通知你关键事件。
订阅模式支持所有形式的输入。
订阅模式覆盖上下文模式 - 也就是说,如果键盘上的某个键已使用订阅模式订阅,则上下文模式不会针对该键盘上的该键触发。
SubscribeKey 覆盖 SubscribeKeyboard - 也就是说,如果您订阅了同一键盘上的所有键和特定键,那么如果您按下特定键,它的回调将触发,而 SubscribeKeyboard 的回调不会。
每个订阅端点也有一个相应的取消订阅端点,它会删除订阅和与之关联的任何块。
键盘和鼠标订阅函数都有一个可选concurrent参数。这控制是否按顺序触发回调。
False(默认)意味着在最后一个回调完成之前不会触发新的回调。这对于涉及鼠标移动的订阅特别有用。
True 表示每个回调都将使用一个新线程。如果您的回调中有一个长时间运行的循环,这可能意味着回调可能会中断先前的回调,从而导致回调的稳定累积(读取内存泄漏)。使用风险自负!

订阅键盘键

订阅特定键盘上的特定键

SubscribeKey(, , , , )
UnsubscribeKey(, ) 例如
AHI.SubscribeKey(keyboardId, GetKeySC(“1”), true, Func(“KeyEvent”))
回调函数被传递状态0(释放)或1(按下)
KeyEvent(state){ ToolTip % “State: “ state }

订阅特定键盘上的所有键

SubscribeKeyboard(, , , )
例如
AHI.SubscribeKeyboard(keyboardId, true, Func(“KeyEvent”))
回调函数传递按键和状态的扫描码
KeyEvent(code, state){ ToolTip % “Keyboard Key - Code: “ code “, State: “ state }

订阅鼠标按钮

订阅特定鼠标上的特定按钮

SubscribeMouseButton(,