【发布时间】:2010-12-30 04:38:59
【问题描述】:
似乎如果您在全局 WH_KEYBOARD_LL 挂钩中调用 ToAscii() 或 ToUnicode(),并且按下了死键,它将被“销毁”。
例如,假设您已将 Windows 中的输入语言配置为西班牙语,并且您想在程序中键入带重音符号的字母 á。通常,您会按单引号键(死键),然后按字母“a”,然后屏幕上会按预期显示带重音符号的 á。
但是,如果您在低级键盘挂钩函数中调用 ToAscii() 或 ToUnicode(),这将不起作用。似乎死键已被破坏,因此屏幕上没有显示重音字母 á。删除对上述函数的调用可以解决问题……但不幸的是,我需要能够调用这些函数。
我用谷歌搜索了一段时间,虽然很多人似乎有这个问题,但没有提供好的解决方案。
任何帮助将不胜感激!
编辑:我正在调用ToAscii(),将LowLevelKeyboardProc钩子函数中收到的虚拟键代码和扫描代码转换为将在屏幕上为用户显示的结果字符.
我试过MapVirtualKey(kbHookData->vkCode, 2),但这不像ToAscii()那样“完整”的功能;例如,如果您按 Shift + 2,您将得到“2”,而不是“@”(或者任何 Shift + 2 将为用户的键盘布局/语言产生的任何内容)。
ToAscii() 是完美的……直到按下死键。
EDIT2:这是钩子函数,删除了不相关的信息:
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);
}
【问题讨论】:
-
请显示调用 ToUnicode() 的代码。你从哪里得到 lpKeyState 参数?
-
@jdigital:嗯,我亲自打电话给 ToAscii,但我读过 ToUnicode 也会发生这种情况。我的电话基本上是 WH_KEYBOARD_LL 挂钩函数中的 ToAscii(kbHookData->vkCode, kbHookData->scanCode, GetKeyboardState(), &lpchar, 0) 。当 ToAscii 调用返回 -1 时,这意味着按下了一个死键......并且正如我在上面解释的那样,这个死键被“销毁”。
-
我删除了我的答案,这是完全不正确的,因为假设您指的是 c-runtime 函数来转换字符串而不是 Win32 apis 来转换扫描码......对不起。
-
如果您能描述这样做的目的,我会很有帮助,我们可能会为您的问题找到其他解决方案。
-
@Sorin:有关更多信息,请参阅对我的原始问题的编辑。 :-)
标签: windows unicode diacritics keyboard-hook