ToUnicode 不返回正确的字符



我试图在一个低级键盘挂钩内调用ToUnicode,并打印它返回的字符。然而,该函数似乎没有考虑是否按下了特殊键,如shift或caps lock,因此输出与MapVirtualKey函数相同,并将当前键的虚拟代码作为参数传递。

例如(pressed keys => characters returned by ToUnicode(:

abcd => abcd (correct)
[caps lock]abcd => abcd (wrong: should be ABCD)
ab[holding shift]cd => abcd (wrong: should be abCD)

我如何调用函数(在钩子过程中(:

KBDLLHOOKSTRUCT* pressedKeyInformation = (KBDLLHOOKSTRUCT*)lParam;
BYTE keysStates[256]; // 256 bo tyle virtualnych klawiszy wpisze GetKeyboardState
if(!GetKeyboardState(keysStates))
//error
else
{
WCHAR charactersPressed[8] = {};
int charactersCopiedAmount = ToUnicode(pressedKeyInformation->vkCode, pressedKeyInformation->scanCode, keysStates, charactersPressed, 8, 0);
//std::wcout << ...
}

后来我注意到,在ToUnicode之前用任何作为参数传递的虚拟密钥代码(例如VK_RETURNVK_SHIFT(调用GetKeyState会导致它返回正确的字符,例如:

abcd => abcd (correct)
[caps lock]abcd => ABCD (correct)
ab[holding shift]cd => abCD (correct)

它还返回用AltGr按下的键盘区域设置相关键,例如[AltGr]a => ą

上面的例子并不完全正确,因为出现了另一个问题-例如,如果按下了大写锁定键,下一个字符仍然取决于它以前的状态,只有后面的字符受到影响,例如:

abcd => abcd (correct)
(caps lock is off)[caps lock]abcd => aBCD (wrong: should be ABCD)
(caps lock is off)ab[caps lock]cd => abcD (wrong: should be abCD)

你知道GetKeyState(<whatever>)为什么会解决其中一个问题吗?后一个盖帽锁(和其他特殊钥匙(问题的原因是什么?

部分答案:

Windows文档建议GetKeyboardStateGetKeyState为相应的键返回类似的结果,当在Windows消息循环中使用这些函数时,情况也是如此,在该循环中,键盘消息得到了正确的转换。

然而,在这种情况下,我们有一个钩子函数,GetKeyboardState没有正确填充键盘。首先调用GetKeyState,将更改键盘状态,随后对GetKeyboardState的调用将按预期工作。我不知道为什么!

其他奇怪的是,GetKeyState返回SHORT值,而GetKeyboardState填充BYTE数组。但这不应该有什么不同,因为我们只对高位和低位感兴趣。

HHOOK hook;
LRESULT CALLBACK hook_procedure(int code, WPARAM wparam, LPARAM lparam)
{
if(code == HC_ACTION)
{
if(wparam == WM_KEYDOWN)
{
KBDLLHOOKSTRUCT *kb = (KBDLLHOOKSTRUCT*)lparam;
BYTE state[256] = { 0 };
wchar_t str[10] = { 0 };
GetKeyState(VK_SHIFT);
GetKeyState(VK_MENU);
GetKeyboardState(state);
if (ToUnicode(kb->vkCode, kb->scanCode, 
state, str, sizeof(str)/sizeof(*str) - 1, 0) > 0)
{
if(kb->vkCode == VK_RETURN) std::wcout << "rn";
else std::wcout << str;
}
}
}
return CallNextHookEx(hook, code, wparam, lparam);
}

相关内容

  • 没有找到相关文章

最新更新