我想触发键盘上的按键。在物理键盘上-使其必须以该特定键盘为源通过所有内核过滤器。这样的事情甚至有可能吗?
我查看了DeviceIOCtrl和IOCTL_KEYBOARD_INSERT_DATA,但没有找到文档。有人说,它是not implemented in the driver。另一个消息源尝试使用IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER,但也说it might not be usable for that kind of stuff。
还有其他选项可以在键盘通过内核过滤器之前触发键盘上的按键吗?
我为什么还要这么做? 是的,这可能是一个X-Y问题,但这是我目前能想到的唯一解决方案。我只想拦截来自特定键盘的键。有RawInput,它告诉我键盘的击键,但不能拦截它,还有一个LowLevel Keyboard钩子可以拦截,但无法识别键盘。更糟糕的是,RawInput在LowLevel-Hook触发之后触发 ,因此在截取按键之前不可能先获得Keyboard。有一些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可能无法解决,在应用程序启动时手动按下按钮以识别键盘的不便。
答案 0 :(得分:0)
我认为我找到了适合我的解决方案/黑客。我当时回避问题中描述的魔术独角兽,并坚持使用已经拥有的驾驶员。
第一个想法来了,当我意识到我已经能够将键盘笔触注入到内核土地中时。只是不是特定的键盘,而是随机的键盘。我最初计划使用RawInput查询所有可用的HID键盘,然后将每个项目与驱动程序中的ID相关联。但是为什么不这样做呢?插入带有按键的随机设备ID,然后等待RawInput触发相应的键盘。
这就是我所做的。我告诉驱动程序为特定设备注入按键,并等待按键到达RawInput。仅发生两个问题:
所以我只需要找到一个根本不起作用的键。幸运的是,驱动程序可以使用扫描代码。 This document告诉我,有许多免费的扫描代码(0x55-0x7f),每个制造商都在其中进行自定义。这样一来,我就开始通过盲目地将那些ScanCode激发到驱动程序中来扫描并在RawInput-API中寻找结果。
免责声明:如果要执行此操作,最好至少有两个屏幕,并确保焦点窗口不在Visual Studio的顶部,因为焦点窗口会立即变为全屏状态,并且只要窗口对准焦点,键盘就会停止工作...即使您恢复键盘控制,也无法退出全屏显示...
事实上,似乎有很多免费的扫描代码可供选择。但是其中一些在不同的国家使用或未在所有键盘驱动程序上触发。我选择了ScanCode 0x7e,它可以转换为KeyCode 194,似乎没有用任何语言,但可以在我拥有的所有(2)个键盘上使用。
此外,此“键”始终包含适当的键盘手柄,因此没有与内容相关的问题。因此,作为最后的实现,我使用RawInput-API获取已连接键盘的数量,并循环选择所有可能的ID(0-10 / 20ish以防止过多的查找/等待),直到找到每个键盘的ID。而且由于扫描代码未用于任何用途,因此不会因突然的大写锁定或任何操作而中断用户。另外,每次重新插入键盘时都需要重做一次,因为插入的每个设备都会获得一个新的ID,即使之前已经有一个ID。