我正在尝试使用ToUnicode
功能来响应收到WM_KEYDOWN
通知,这听起来比现在容易得多。
实际上,如果只使用ToUnicode
,WM_CHAR
应该是多余的,但令我惊讶的是,它实际上根本无法正常工作!我已经在非共同控制程序中使用WM_CHAR
多年了,我只是第一次输入一个带有变音符号 1 的单词,只是为了意识到死键没有'干得好!
例如,如果我输入“e
”,则WM_CHAR
会告诉我e
何时应该告诉é
(类似于其他死键组合,例如{ {1}})。
â
似乎是一个显而易见的解决方案 - 实际上很笨拙,它的MSDN描述页面表明它完全符合我的需要。它确实需要很多参数,但那些似乎直截了当。
第一个参数只是虚拟键码(ToUnicode
),第二个参数可以通过wParam
获得。
第三个参数是可选的,所以实际上并不需要(这就是“可选”的意思,不是它!)。这是第一个惊喜:如果不提供键状态,则按下的任何键的功能都会失败(“无键映射”)。这意味着需要额外调用MapVirtualKey
。
这给我们留下了这段代码:
GetKeyboardState
这会为每个普通字符输出正确的Unicode字符(没有大的成就,你已经从case WM_KEYDOWN:
BYTE kb[256];
GetKeyboardState(kb);
WCHAR uc[5] = {};
switch(ToUnicode(wParam, MapVirtualKey(wParam, MAPVK_VK_TO_VSC), kb, uc, 4, 0))
{
case -1: _putws(L"dead key"); break;
case 0: _putws(L"no idea!"); break;
case 1:
case 2:
case 3:
case 4:
_putws(uc);
}
...
得到了这个),但是对于死键来说却完全失败了,完全相同(有人可能会怀疑WM_CHAR
使用TranslateMessage
来生成ToUnicode
)
shift和alt键以及altgr都很荣幸(例如,键入WM_CHAR
(altgr-m)会让我µ
就好了),但变音符号死键(如急性或抑扬)不行。这意味着如果您尝试在我的德语布局键盘上键入一些法语或西班牙语单词,那就没有运气了。
有没有办法正确使用此功能,所以它有效吗?或者,是否有一个不同的功能适用于死键?
<小时/> 1 嗯,显然不是第一次,但是第一次在这种情况下。
答案 0 :(得分:2)
我无法确认您描述的症状。我使用Spy ++来监控记事本收到的消息。然后我按了死键´
,然后按了e
。
正如您所看到的,WM_CHAR
消息绝对正确,Unicode字符233.代表é
。
<00001> 000F0C86 P WM_KEYDOWN nVirtKey:VK_OEM_6 cRepeat:1 ScanCode:0D fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00002> 000F0C86 P WM_DEADCHAR chCharCode:'180' (180) cRepeat:1 ScanCode:0D fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00003> 000F0C86 P WM_KEYUP nVirtKey:VK_OEM_6 cRepeat:1 ScanCode:0D fExtended:0 fAltDown:0 fRepeat:1 fUp:1
<00004> 000F0C86 P WM_KEYDOWN nVirtKey:'E' cRepeat:1 ScanCode:12 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00005> 000F0C86 P WM_CHAR chCharCode:'233' (233) cRepeat:1 ScanCode:12 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00006> 000F0C86 P WM_KEYUP nVirtKey:'E' cRepeat:1 ScanCode:12 fExtended:0 fAltDown:0 fRepeat:1 fUp:1
因此,WM_CHAR
是您只需要组合输入所需的一切。否则,您可以处理WM_DEADCHAR
并手动处理输入。
请阅读有关MSDN上keyboard input的文档。