使用 ToUnicode(正确,所以它有效)

Dam*_*mon 5 unicode winapi input

我正在尝试使用该ToUnicode功能来响应收到WM_KEYDOWN通知,这听起来比实际容易得多。

实际上,ToUnicode如果简单地使用 应该是多余的WM_CHAR,但令我惊讶的是,这实际上根本无法正常工作!已经使用WM_CHAR在无共控件的程序了好半天,我刚刚在第一次输入一个字用变音口音1只认识到死键不会在所有的工作!
例如,如果我输入 ´ e,那么WM_CHAR它会告诉我e什么时候应该告诉我é(类似于其他死键组合,例如â)。

ToUnicode根据其文档,这似乎是显而易见的解决方案——尽管它很笨拙,但它的 MSDN 描述页面指出它完全符合我的需要。它确实需要大量参数,但这些参数似乎简单。

第一个参数只是虚拟键码 ( wParam),第二个参数可以通过 获得MapVirtualKey
第三个参数是可选的,所以实际上不需要(这就是“可选”的意思,不是吗!)。这是第一个惊喜:如果您提供键状态,则对于您按下的任何键,该功能都会失败(“没有键映射”)。这意味着需要额外调用GetKeyboardState

这给我们留下了这段代码:

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);
    }
...
Run Code Online (Sandbox Code Playgroud)

这会为每个普通字符输出正确的 Unicode 字符(没什么大的成就,你已经从 中得到了WM_CHAR),但是对于死键,以完全相同的方式(人们可能怀疑TranslateMessage用于ToUnicode生产WM_CHAR)却非常失败。
shift 和 alt 键以及 altgr 都受到尊重(例如,键入µ(altgr-m) 会给我µ很好的效果),但变音符号死键(如锐键或抑扬符)不起作用。这意味着如果您尝试在我的德语布局键盘上输入一些法语或西班牙语单词,那您就没有运气了。

有没有办法正确使用这个功能,所以它有效?或者,是否有不同的功能适用于死键?


1嗯,显然不是第一次,而是第一次在这种情况下

xMR*_*MRi 3

我无法证实你所描述的症状。我使用 Spy++ 来监视记事本收到的消息。然后我按下了死键\xc2\xb4,然后按了e

\n\n

正如您所看到的,该WM_CHAR消息对于 Unicode 字符 233 来说是绝对正确的。它代表\xc3\xa9

\n\n
<00001> 000F0C86 P WM_KEYDOWN nVirtKey:VK_OEM_6 cRepeat:1 ScanCode:0D fExtended:0 fAltDown:0 fRepeat:0 fUp:0\n<00002> 000F0C86 P WM_DEADCHAR chCharCode:\'180\' (180) cRepeat:1 ScanCode:0D fExtended:0 fAltDown:0 fRepeat:0 fUp:0\n<00003> 000F0C86 P WM_KEYUP nVirtKey:VK_OEM_6 cRepeat:1 ScanCode:0D fExtended:0 fAltDown:0 fRepeat:1 fUp:1\n<00004> 000F0C86 P WM_KEYDOWN nVirtKey:\'E\' cRepeat:1 ScanCode:12 fExtended:0 fAltDown:0 fRepeat:0 fUp:0\n<00005> 000F0C86 P WM_CHAR chCharCode:\'233\' (233) cRepeat:1 ScanCode:12 fExtended:0 fAltDown:0 fRepeat:0 fUp:0\n<00006> 000F0C86 P WM_KEYUP nVirtKey:\'E\' cRepeat:1 ScanCode:12 fExtended:0 fAltDown:0 fRepeat:1 fUp:1\n
Run Code Online (Sandbox Code Playgroud)\n\n

WM_CHAR如果您只想要组合输入,那么您需要的一切都是如此。否则,您可以WM_DEADCHAR手动处理和处理输入。

\n\n

请阅读 MSDN 上有关键盘输入的文档。

\n