windows - 键盘 Hook 中的 ToAscii/ToUnicode 会破坏死键

标签 windows unicode diacritics keyboard-hook

似乎如果您在全局 WH_KEYBOARD_LL Hook 中调用 ToAscii()ToUnicode(),并且按下死键,它将被“销毁” '.

例如,假设您在 Windows 中将输入语言配置为西类牙语,并且您想要在程序中键入带重音符号的字母 á。通常,您会按单引号键(死键),然后按字母“a”,然后屏幕上会按预期显示带重音符号的 á

但是,如果您在低级键盘 Hook 函数中调用 ToAscii()ToUnicode(),这将不起作用。似乎死键被破坏了,所以屏幕上没有显示重音字母 á 。删除对上述函数的调用可以解决问题...但不幸的是,我需要能够调用这些函数。

Google 了一会儿,似乎很多人都有这个问题,但没有提供好的解决方案。

如有任何帮助,我们将不胜感激!

编辑: 我正在调用 ToAscii() 来转换我的 LowLevelKeyboardProc 中收到的虚拟键码和扫描码将函数挂接到将在屏幕上为用户显示的结果字符。

我尝试了 MapVirtualKey(kbHookData->vkCode, 2),但这不是像 ToAscii() 那样“完整”的函数;例如,如果您按 Shift + 2,您将得到“2”,而不是“@”(或者任何 Shift + 2 将为用户的键盘布局/语言生成)。

ToAscii() 是完美的……直到按下死键。

EDIT2:这是钩子(Hook)函数,删除了不相关的信息:

LRESULT CALLBACK keyboard_LL_hook_func(int code, WPARAM wParam, LPARAM lParam) {

    LPKBDLLHOOKSTRUCT kbHookData = (LPKBDLLHOOKSTRUCT)lParam;
    BYTE keyboard_state[256];

    if (code < 0) {
        return CallNextHookEx(keyHook, code, wParam, lParam);
    }

    WORD wCharacter = 0;

    GetKeyboardState(&keyboard_state);
    int ta = ToAscii((UINT)kbHookData->vkCode, kbHookData->scanCode,
                     keyboard_state, &wCharacter, 0);

    /* If ta == -1, a dead-key was pressed. The dead-key will be "destroyed"
     * and you'll no longer be able to create any accented characters. Remove
     * the call to ToAscii() above, and you can then create accented characters. */

    return CallNextHookEx(keyHook, code, wParam, lParam);
}

最佳答案

很老的话题了。不幸的是,它没有包含我正在寻找的答案,而且似乎没有一个答案能正常工作。我终于通过检查 MSB 解决了问题MapVirtualKey 函数,在调用 ToUnicode/ToAscii 之前。似乎很有魅力:

if(!(MapVirtualKey(kbHookData->vkCode, MAPVK_VK_TO_CHAR)>>(sizeof(UINT)*8-1) & 1)) {
    ToAscii((UINT)kbHookData->vkCode, kbHookData->scanCode,
        keyboard_state, &wCharacter, 0);
}

MapVirtualKey 的返回值上引用 MSDN,如果使用 MAPVK_VK_TO_CHAR:

[...] Dead keys (diacritics) are indicated by setting the top bit of the return value. [...]

关于windows - 键盘 Hook 中的 ToAscii/ToUnicode 会破坏死键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1964614/

相关文章:

c# - 如何以 C# 编程方式或命令行打开 explorer.exe 到 "Recycle Bin"

从R中的字符串中删除表情符号

javascript - sIFR:动态插入变音符号会导致麻烦

c++ - 使用ICU将UTF-8转换为UCS2导致乱码

python - 在 Python 2.x 中转换 u'\xe 0' to '\u00E0'?

带有变音符号和连字的 Python 3 正则表达式,

smalltalk - 如何从字符串中删除变音符号(变音符号)?

c++ - 崩溃时如何为我的进程创建小型转储?

c++ - 使用 loadappinit_dlls 注册表项将 dll Hook 到正在运行的进程中

c++ - 将 WebRTC (AudioTrackSinkInterface) 原始音频写入光盘