键盘挂钩中的ToAscii/ToUnicode会破坏死键 [英] ToAscii/ToUnicode in a keyboard hook destroys dead keys

查看:149
本文介绍了键盘挂钩中的ToAscii/ToUnicode会破坏死键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果在全局WH_KEYBOARD_LL挂钩中调用ToAscii()ToUnicode(),并且按下了死键,它将被破坏".

It seems that if you call ToAscii() or ToUnicode() while in a global WH_KEYBOARD_LL hook, and a dead-key is pressed, it will be 'destroyed'.

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

For example, say you've configured your input language in Windows as Spanish, and you want to type an accented letter á in a program. Normally, you'd press the single-quote key (the dead key), then the letter "a", and then on the screen an accented á would be displayed, as expected.

但是,如果您在低级键盘挂钩函数中调用ToAscii()ToUnicode(),则此操作将无效.似乎该死键已被破坏,因此屏幕上没有出现带重音的字母á.删除对上述函数的调用可以解决此问题……但是,不幸的是,我需要能够调用这些函数.

But this doesn't work if you call ToAscii() or ToUnicode() in a low-level keyboard hook function. It seems that the dead key is destroyed, and so no accented letter á shows up on screen. Removing a call to the above functions resolves the issue... but unfortunately, I need to be able to call those functions.

我搜索了一段时间,虽然很多人似乎都遇到了这个问题,但没有提供好的解决方案.

I Googled for a while, and while a lot of people seemed to have this issue, no good solution was provided.

任何帮助将不胜感激!

我正在调用ToAscii()来转换我的

I'm calling ToAscii() to convert the virtual-key code and scan code received in my LowLevelKeyboardProc hook function into the resulting character that will be displayed on screen for the user.

我尝试了MapVirtualKey(kbHookData->vkCode, 2),但这还不能像ToAscii()那样完成"一个功能.例如,如果您按Shift + 2,您将得到"2",而不是"@"(或将为用户的键盘布局/语言产生的Shift + 2).

I tried MapVirtualKey(kbHookData->vkCode, 2), but this isn't as "complete" a function as ToAscii(); for example, if you press Shift + 2, you'll get '2', not '@' (or whatever Shift + 2 will produce for the user's keyboard layout/language).

ToAscii()很完美...直到按下死键为止.

ToAscii() is perfect... until a dead-key is pressed.

这是挂钩函数,其中删除了不相关的信息:

Here's the hook function, with irrelevant info removed:

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.似乎像一种魅力一样工作:

Quite an old thread. Unfortunately it didn't contain the answer I was looking for and none of the answers seemed to work properly. I finally solved the problem by checking the MSB of the MapVirtualKey function, before calling ToUnicode / ToAscii. Seems to be working like a charm:

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

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

Quoting MSDN on the return value of MapVirtualKey, if MAPVK_VK_TO_CHAR is used:

[...]死键(变音符号)通过设置返回值的高位来指示. [...]

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

这篇关于键盘挂钩中的ToAscii/ToUnicode会破坏死键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆