我尝试使用MapVirtualKey[A]/[W]/[ExA]/[ExW]
API通过MAPVK_VK_TO_CHAR (2)
模式将VK_*
代码Map到字符。
我发现无论我使用哪种键盘布局,它总是为'VK_A'..'VK_Z'
返回'A'..'Z'
字符。
The docs表示:
uCode参数是一个虚拟键代码,并被转换为返回值的低位字中未移位的字符值。通过设置返回值的顶部位来指示死键(变音符号)。如果没有转换,则函数返回0。
但是我不能从它得到unshifted character value
也不是非ASCII字符。
对于其他按钮,它的工作原理如上所述。考虑到这种行为甚至更烦人,例如对于美国英语键盘布局,它返回:
VK_Q (0x51) -> `Q` (U+0051 Latin Capital Letter Q)
VK_OEM_PERIOD (0xbe) -> `.` (U+002E Full Stop)
但对于俄语键盘布局,它返回:
VK_Q (0x51) -> `Q` (U+0051 Latin Capital Letter Q)
^- here it should return `й` (U+0439 Cyrillic Small Letter Short I) according to docs
VK_OEM_PERIOD (0xbe) -> `ю` (U+044E Cyrillic Small Letter Yu)
如何正确使用?
1条答案
按热度按时间gywdnpxw1#
MapVirtualKey
有一个known broken behaviour。**2023年1月更新:**Microsoft docs was updated包含此行为。
The docs是骗你关于
MAPVK_VK_TO_CHAR
或2
模式。根据实验和leaked Windows XP source code(在
\windows\core\ntuser\kernel\xlate.c
文件中),它包含'A'..'Z' VKs的不同行为(这些VKs在Win32 APIWinUser.h
头中没有明确定义,相当于'A'..'Z' ASCII字符):不知道为什么微软决定从Win 3. 1中删除这个错误,但我的Windows 10上的当前情况是这样的。
此外,some keyboard layouts可以在一次按键上发出多个WCHAR字符(UTF-16 surrogate pairs或可以包含多个Unicode代码点的连字)。
MapVirtualKey
与MAPVK_VK_TO_CHAR
也无法为这些键返回正确的值-在这种情况下,它将返回U+F002代码点。作为一种解决方法,我可以建议您使用ToUnicode[Ex] API,它可以为您完成此Map:
或者更好:如果您有Win32消息循环-只需使用
TranslateMessage()
(在后台调用ToUnicode()
),然后处理WM_CHAR
消息。PS:这同样适用于
GetKeyNameText
API,因为它在键盘布局dll中没有显式名称设置的键的后台调用MapVirtualKey(vk, MAPVK_VK_TO_CHAR)
(通常只有非字符才有名称)。