【发布时间】:2020-11-04 07:25:16
【问题描述】:
我想在键盘上触发 Keypress。在物理键盘上 - 因此它必须以该特定键盘作为其源来遍历所有内核过滤器。这样的事情可能吗?
我查看了 DeviceIOCtrl 和 IOCTL_KEYBOARD_INSERT_DATA,但没有找到文档。有人说是not implemented in the driver。另一个 Source 尝试使用 IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER,但也说,it might not be usable for that kind of stuff。
是否有其他选项可以在键盘通过内核过滤器之前触发键盘按键?
我为什么要这样做? 是的,这可能是一个 X-Y 问题,但它是我目前能想到的唯一解决方案。我只想截取来自特定键盘的键。有 RawInput,它告诉我击键的键盘,但不能拦截它,还有一个 LowLevel Keyboard 钩子可以拦截,但无法识别键盘。更糟糕的是,RawInput 在 LowLevel-Hook 之后触发,因此在截取击键之前无法获取键盘。有一些 magic unicorn way 使用在 RawInput 之后触发的全局 Hook,但处理所有边缘情况看起来很痛苦。
有一个API out there 来拦截我选择的键盘敲击。它基本上安装了一个允许拦截击键并获取键盘ID的驱动程序。但是:该 ID 有点随意,并且不遵循我可以用来将整数值与特定键盘设备相关联的任何规则。例如。它在重新插入设备时会发生变化,与 \Device\KeyboardClassX 等无关。因此,每次重新连接键盘/启动应用程序时,用户都必须主动按下一个键,以便我可以确定哪个物理键盘的 id 实际代表。我想避免这种情况并自动获取特定设备的 ID。我的想法是触发键盘(-控制器?)中的按键并使用驱动程序捕获它,从而将任意 ID 与设备相关联。
因此,如果我的 Y 有不同的 X,请随时提出建议。我想避免所有那些Magic Unicorn Way of RawInput and GlobalHook 不能可靠工作的边缘情况。任何主要语言的示例都可以。也许没有办法解决在应用程序启动时手动按下按钮来识别键盘的 UX 不便......
【问题讨论】:
-
"更糟糕的是,RawInput 在 LowLevel-Hook 之后触发" - 您链接到的文章通过使用标准键盘挂钩而不是低级键盘挂钩。
WH_KEYBOARD_LL在 RawInput 事件之前触发,WH_KEYBOARD在事件之后触发。 -
另外,如果您阅读文章底部的 cmets,有人建议使用
WH_GETMESSAGE挂钩而不是WH_KEYBOARD挂钩,以便 RawInput 事件和键盘事件可以用一个钩子处理。不过,我没有尝试看看它是否有效。 -
@Remy Lebeau 您的第一条评论的问题是许多边缘情况不能可靠地工作,我想避免这些情况。我会浏览那篇文章中的 cmets,还没有这样做。
-
缺少编写自定义键盘驱动程序,您真的找不到更好的解决方案。这些是唯一可用于拦截/修改用户模式代码中的键盘输入的 API。
-
@RemyLebeau 我知道这一点。幸运的是,已经存在一个驱动程序,但它有一些限制,我想通过使用我的问题的前半部分来解决。正如我所说,拦截不是问题,关联是一件棘手的事情。如果我在使用它,我不妨尝试将 Windows API 用于非预期目的。
标签: c++ winapi input keyboard deviceiocontrol