windows - 有没有办法在Windows键盘驱动程序中模拟箭头键?

标签 windows unicode driver keyboard-layout wdk

我目前正在为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,并使用此结构来解释这些代码。

第一个重要的是pusVSCtoVKpVSCtoVK_E0pVSCtoVK_E1,它们将驱动程序的原始扫描代码(和扩展扫描代码)映射到与硬件无关的虚拟键码。这些键代码描述了键。字符映射稍后出现。因此,即使布局稍后将其转换为其他内容,左光标键也将生成VK_LEFT,而S键将生成VK_S

接下来是pCharModifiers,它指定哪些虚拟键是修饰键,以及哪些组合产生不同的移位状态。

最后是pVkToWcharTable,它根据移位状态将所有虚拟键映射到Unicode字符。这是大多数实际布局所在的位置。死键和连字有一些特殊的值,但现在让我们将其放在一边。

应用领域

现在,应用程序最终得到了什么?显然,他们可以从通常的窗口消息中获取虚拟键码和扫描码,例如WM_INPUTWM_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/

相关文章:

python - 运行使用py2exe编译的可执行文件时出错

Windows DNS 控制台 (DNSMgmt.msc) - 以其他域用户身份运行

c++ - 如何从控件中正确检索 Unicode 文本?

windows - 在 Windows 上加载 .sys 驱动程序的实用程序

windows - Windows XP 嵌入式中的 CUDA

c++ - 如何让 C++ 在关闭控制台时执行函数

windows - 安装似乎已损坏[不支持]-Visual Studio代码

django - 如何在 Django 1.5 中获得对 rfc6532(电子邮件地址地址部分中的 unicode)的支持?

python - 为什么 "ǃ".isalpha() 为 True 而 "!".isalpha() 为 False?

linux - Mt7630e驱动在Fedora27上搭建安装