我目前正在为Windows编写键盘驱动程序,它提供了一个附加的修饰符,并允许直接键入一些附加字符。例如,实际的引号(“,”,“,”,…)和一些数学字符(ℕ,ℝ,ℚ,ℤ,√,…)。
现在,我想像那样提供箭头键。 (alt_gr + e =向上; alt_gr + s =左侧; alt_gr + d =向下; alt_gr + f =右侧)
所以我的问题是,如果箭头键有Unicode控制字符,则可以在aVkToWcharTable或其他解决方案中使用。这真的很有帮助。
最佳答案
我没有Windows驱动程序编程的任何经验,因此,如果有人发现错误,请纠正我。
但是,我使用NEO布局(确切地说是AdNW变体)并且很好奇,因此我下载了DDK,以了解可以从文档中学到什么。我真的没有适合您的解决方案,我想您可能已经知道其中的一些内容,但是我认为写下我发现的内容可能仍然有用,即使只是为了使事情更简单。
概述
据我所知,键盘数据可以来自两个路径。有PS/2设备,然后有USB键盘。两者都采用不同的路径(USB数据的来源来自HID基础架构,PS/2数据由I8042prt驱动程序生成),但最终以所谓的“键盘类驱动程序”结尾。
从那里开始,数据将传递到DirectInput或user32旧式接口(interface)。目前尚不清楚布局在哪里起作用,但我认为它是在Keyboard类驱动程序的顶部实现的。
布局
键盘布局似乎基本上是一堆数据结构,符合kbd.h中定义的KBDTABLES
结构。基本上,低层驱动程序会生成ScanCode,并使用此结构来解释这些代码。
第一个重要的是pusVSCtoVK
,pVSCtoVK_E0
和pVSCtoVK_E1
,它们将驱动程序的原始扫描代码(和扩展扫描代码)映射到与硬件无关的虚拟键码。这些键代码描述了键。字符映射稍后出现。因此,即使布局稍后将其转换为其他内容,左光标键也将生成VK_LEFT
,而S键将生成VK_S
。
接下来是pCharModifiers
,它指定哪些虚拟键是修饰键,以及哪些组合产生不同的移位状态。
最后是pVkToWcharTable
,它根据移位状态将所有虚拟键映射到Unicode字符。这是大多数实际布局所在的位置。死键和连字有一些特殊的值,但现在让我们将其放在一边。
应用领域
现在,应用程序最终得到了什么?显然,他们可以从通常的窗口消息中获取虚拟键码和扫描码,例如WM_INPUT
,WM_KEYDOWN
,...。他们还可以使用诸如ToUnicodeEx
之类的功能来查询Unicode字符的布局。布局提供了虚拟键代码和Unicode字符。
对于普通字符,一切都很好。该应用程序将接收输入事件,询问布局的字符,然后就可以了。但是,光标键有所不同,因为从虚拟键到字符的映射既不需要也不有意义。应用程序关心 key ,而不关心字符。因此,它将根据虚拟键码执行操作。如果是VK_LEFT
,则将光标向左移动。如果是VK_RIGHT
,则光标向右移动,依此类推。
这给我们带来了一个难题:如果我们想让ModX + S向左移动光标,则意识到修饰符的pVkToWcharTable
将无济于事,因为应用程序从不要求输入字符,而要求输入键。显然,S与左键不是同一键。产生一个控制字符(据我所知尚不存在)很可能也无济于事,因为应用程序不会要求它也不会解释它。
因此,您真正想要的是,如果按下适当的修饰键,则S键会生成不同的虚拟键代码,但是布局的数据结构不允许这种映射。毕竟它不是在执行代码,而只是在执行数据结构。
那Numpad呢?
Numpad似乎可以满足要求。 key 的扫描代码保持不变,但是根据Numlock状态,它们会生成不同的虚拟 key 代码。但是,我认为Windows在这里做了一些特殊的处理。这些键在KBDNUMPAD
中设置了pusVSCtoVK
标志。似乎Windows会检测到该错误并根据Numlock状态交换虚拟键。
我至少找到了一些证据。尝试在Google中搜索“xxxNumpadCursor”。出现了一些看似泄漏的Windows代码。根据Shift和Numlock,检查KBDNUMPAD
以及似乎替换虚拟键的代码。我怀疑是否可以将其用于此目的。
可能吗
那么,如果布局无法做到这一点,谁能做到呢?显然,某些较低级别的驱动程序会产生原始扫描代码。 DDK中有一个所谓的过滤器驱动程序的示例,称为“kbfiltr”。基本上,这样的筛选器驱动程序似乎可以连接到现有驱动程序之上,并重写来自该驱动程序的数据,因此,如果按下另一个键,则应该可以将S键的扫描代码重写为Left。
但是请注意,这将是驱动程序,而不是布局。我不确定这是否可行。据我所知,不知道所选的布局,因此更改将适用于所有布局。 (尽管有可能在此处实现整个布局,并带有将其关闭的键。)我也不确定这种驱动程序的安装有多复杂,以及是否需要对驱动程序进行签名,这将使情况更糟。
我真的没有足够的驱动程序编程经验(也就是说完全没有经验),无法推荐或反对这种方法。可能值得进行一些试验(我在这里更喜欢使用虚拟机),但是它似乎比当前完成的简单布局替换更具挑战性。 Autohotkey解决方案可能仍然是最好的解决方案(缺点是它不适用于所有应用程序)。
更新
我做了一些研究。我认为使用过滤器驱动程序可以做到这一点。该驱动程序基本上位于HID基础结构或I8042prt驱动程序与Keyboard类驱动程序之间。然后,它可以在数据到达类驱动程序之前对其进行修改,并在它们到达那里之前替换/删除/添加键事件。最后,您将不得不使用特殊的布局(用于其他unicode字符)以及驱动程序,可以通过设备管理器为单个键盘安装该驱动程序。然后,该解决方案应适用于所有应用程序。
这里的问题是驱动程序签名。作为内核模式驱动程序,必须对其进行签名才能加载它,而不会在64位Vista/Win7中造成难看的黑客攻击。而且与驾驶员签约并不便宜,因此您基本上对这种方法不走运。我以为可以通过编写用户模式驱动程序(不需要签名)来避免这种情况,但是问题是,必须将过滤器安装在Keyboard类驱动程序下。令人遗憾的是,用户模式筛选器驱动程序上面不能有内核模式驱动程序。所以这不是一个选择。
因此,我认为您基本上对AutoHotkey感到困惑。除非您愿意并且能够编写内核模式驱动程序并解决签名问题。
关于windows - 有没有办法在Windows键盘驱动程序中模拟箭头键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5298719/