GetKeyNameText 小键盘缺少文本

GetKeyNameText numpad missing text

我正在尝试使用 GetKeyNameText 获取按下的键的名称,使用原始输入给出的 make/scan 代码和扩展键标志:

std::wstring GetKeyName(const RAWKEYBOARD& info)
{
    WCHAR n[128];
    const int l = GetKeyNameTextW((info.MakeCode << 16) | ((info.Flags & RI_KEY_E0) != 0 ? 1 << 24 : 0), n, ARRAYSIZE(n));
    if(l == 0) { return L""; }
    return std::wstring(n);
}

这适用于大多数键,但是,Num /(扫描码 53)和 Num *(扫描码 55)给出错误的结果:他们都给出了字符串 " (ZEHNERTASTATUR)"(德语键盘布局,因此在英语中会是 "Num ")——所以名称中缺少 /*

我用两个不同的键盘测试了这个,结果相同(使用 Windows 10 btw),我是不是遗漏了什么?为什么这两个键的名称不正确?

这是 Windows 中的一个错误,已经存在了很长时间,现在仍然存在。

在这个 article by M. Kaplan from 2012 中,他解释了 Windows 中访问键名的混乱状态。不过,这方面似乎没有太大改进。

键名存储在已编译的键盘布局文件中,这些文件是 DLL,在它们的 .data 部分中,以专有格式导出为 KbdLayerDescriptor。德语键盘布局存储在 C:\Windows\System32\KBDGR.DLL 中。如果你在上面使用 strings 实用程序,你会得到这个(是的,顺序很奇怪):

...
NACH-LINKS
^ZIRKUMFLEX
NACH-RECHTS
STRG-RECHTS
LINKE WINDOWS
NUM-FESTSTELL
RECHTE WINDOWS
BILD-NACH-OBEN
BILD-NACH-UNTEN
UMSCHALT RECHTS
ROLLEN-FESTSTELL
 (ZEHNERTASTATUR)      <<<<<< THE ISSUE EXISTS
 (ZEHNERTASTATUR)      <<<<<< HERE AS WELL!
0 (ZEHNERTASTATUR)
3 (ZEHNERTASTATUR)
2 (ZEHNERTASTATUR)
1 (ZEHNERTASTATUR)
+ (ZEHNERTASTATUR)
6 (ZEHNERTASTATUR)
5 (ZEHNERTASTATUR)
4 (ZEHNERTASTATUR)
...

我们可以通过在十六进制编辑器中查看它来验证这不是 strings' 启发式确定字符串开始和结束的错误:

如您所见,文件中根本不存在 */

看来你被 Windows 给你的坏名字困住了。 (顺便说一句,其他语言也有错误。)即使 Windows shell 本身也存在这个问题,例如当我打开快捷方式的属性并尝试设置热键时会发生这种情况到 Num *:

恐怕您要么不得不忍受它,要么维护自己的修复列表以应用于您获得的损坏信息,或者维护自己单独的密钥名称列表以及相应的翻译...这是其他应用程序似乎在做的事情,例如 VS Code。

(当然,如果这只影响到您或一小部分人,您可以不遗余力地使用 Microsoft Keyboard Layout Creator 和在那里正确设置名称,但这可能会造成太多附带损害(例如 Microsoft 帐户设置同步问题),因此不值得。)