我想在 Windows 11 中将 L/R Shift 与 CapsLock/Enter 键互换。它以前在 Win 10 中可以使用重新定义扫描码映射的注册表技巧。请参阅:
- https://learn.microsoft.com/en-gb/windows-hardware/drivers/hid/keyboard-and-mouse-class-drivers(有关如何在注册表中进行扫描码交换的 MS 文档)
- Windows 11 - 扫描码映射注册表技巧不再有效
上面的问题还提到,如果从 Win 10 升级到 11,它仍然有效,但我全新安装的 Win 11 不再尊重此条目。我猜升级安装过程足够聪明,可以将此设置从注册表复制到其他地方,以便 Win 11 正常工作,但全新安装时,没有什么可复制的。
现在,要进行相同的密钥交换,应该怎么做?我不想使用 Autokey 或其他外部应用程序,只想使用注册表技巧/更改操作系统文件/等。它需要在用户会话(重启后)和登录屏幕中工作。
答案1
经过反复尝试,我找到了原因。不确定其他键是否也一样,但对于 R/L shift 和 CapsLock,Win 11 似乎将其扫描码的第一个字节更改为0xe0
。以前是0x00
。
我以前的解决方案是这样的:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,05,00,00,00,3a,00,2a,00,2a,00,3a,00,36,00,1c,00,1c,00,36,00,00,00,00,00
格式化为每行 2 个字节:
00,00,00,00,
00,00,00,00,
05,00,00,00,
3a,00,2a,00,
2a,00,3a,00,
36,00,1c,00,
1c,00,36,00,
00,00,00,00
阅读鼠标和键盘驱动程序的 MS 文档,我们知道这可以解释如下:
所以,我们需要把扫描码放在两个字节中,低字节在前(小端字节序),字节1和2代表新的扫描码,旧扫描码替换在字节3和4上。
例如,3a,00,2a,00
意思是,找出0x00 0x2a
扫描码为 的键,并用新的扫描码 替换0x00 0x3a
。结果是 L Shift 键充当 CapsLock。3a
是CapsLock
,并且2a
是L Shift
。因为我想交换两者,所以下一行是2a,00,3a,00
,这意味着相反。
接下来的两行类似,交换36
(R SHIFT)和1c
(Enter)。
那么,我们如何找到扫描码呢?MS 扫描码规范,附录 A:Windows 标准 PS/2 扫描代码,有一个表格显示所有扫描码:
,在那里你可以找到与我所说的完全相同的扫描代码:
但是,当我们谈论扫描码时,有 2 个字节。0036
表示高字节为0x00
,低字节为0x36
。 但在表中您还可以看到 2 行上有 2 个值,第一行以高字节00
(空)开头,第二行以 开头E0
,表示0xe0
。 为什么?
我不是专家,所以我只能根据我在同一个文件中读到的内容进行猜测:
带前缀的扫描码 标准 101/102 键键盘(以及 Microsoft Natural 键盘等)上的某些键会发出两个字节的序列,其中第一个字节为 0xE0 或 0xE1。此方法主要用于区分同一键的左右版本,例如,左 Alt 为 0x38,而右 Alt 为 0xE0 0x38。0xE0 前缀表示为 WM_KEYDOWN 等消息的 lParam 中的“扩展位”(位 24)。0xE1 前缀非常少见,但操作方式与 0xE0 前缀类似。它的存在与否不会通过任何方式通过 API 指示。
所以也许第二个值可用于但以前在 Win 10 中不是这样。我在 Win 10 和 Win 11 上使用相同的键盘,因此不可能是同一个键盘突然开始发出不同的高位字节;只能是 Win 11 做了一些改变。
我是怎么发现的?好吧,在我调查的过程中,我发现 SharpKey 可以检测扫描码,当它读取我之前在注册表中的解决方案时,它也认为我的映射基本正确;但是,它显示一个键(Enter)是未知的。当我在 SharpKey 中重新映射时,它告诉我 Enter 是,0xe0 0x1c
并给我一个.reg
类似这样的文件:
3a,00,2a,00, <<< SharpKey still thinks 0x00 is correct value for higher byte
2a,00,3a,00, <<< ditto
36,00,1c,e0, <<< set Enter to use scan code 0x00 0x36
1c,e0,36,00, <<< set R Shift to use scan code 0xe0 0x1c
但是,只有最后一行有效!R shift 将执行 Enter 的工作,但 Enter 不会切换大小写!
这让我想到,现在 Win 11 是否可能只接受0xe0
第一个字节?所以我将所有第一个字节都改为00
,然后e0
一切开始正常工作……
这是 Win 11 中的一个错误吗,它开始只取0xe0
第一个字节???