使用当前键盘布局截取键盘输入

时间:2009-07-22 09:44:20

标签: c# keyboard hook

我使用SetWindowsHookEx()函数实现了一个低级键盘钩子。它工作正常,并返回每次击键的虚拟键码。我可以使用KeyInterop.KeyFromVirtualKey()将此虚拟键代码转换为System.Windows.Input.Key。但目标是在当前键盘布局中获得与此虚拟键代码对应的符号。

即。对于德语布局,我希望Key.Z为“Y”,Key.Y为“Z”。

有人可以提供帮助吗?

谢谢。

3 个答案:

答案 0 :(得分:0)

调用GetKeyboardLayout来检索活动布局值,然后执行一些条件循环以获得所需的结果。

答案 1 :(得分:0)

您应该看看这些方法GetKeyboardStateGetKeyboardLayoutMapVirtualKeyExToUnicodeEx

解决方案应该类似于

byte[] keyboardState = new byte[256];
GetKeyboardState(keyboardState);
IntPtr handle = GetKeyboardLayout(0);
uint scanCode = MapVirtualKeyEx(VirtualKeyCode, 0, handle);
StringBuilder stringBuilder = new StringBuilder(2);

int nResultLower = ToUnicodeEx(VirtualKeyCode, scanCode, keyboardState, stringBuilder,
                                       stringBuilder.Capacity, 0, handle);

string output= string.Empty;
if (nResultLower != 0)
{
  output = stringBuilder.ToString();
}

答案 2 :(得分:0)

我们不太确定我们是在谈论相同的情况,但最近我遇到了类似的问题,其中ToUnicodeEx中断了用户'键击(当使用修饰符如' alt + numpad'或在德语键盘上使用' +'键修饰符)时,如果需要,则会将意外的字母打印到屏幕上。 / p>

在运行ToUnicodeEx之前,将@ Nejchy的代码与ClearKeyboardBuffer方法结合起来解决了我的问题:

private static bool ClearKeyboardBuffer(uint vk, uint sc, IntPtr hkl)
{
    StringBuilder sb = new StringBuilder(10);
    int rc = -1;
    bool isDeadKey = false;
    while (rc < 0)
    {
        rc = user32.ToUnicodeEx(vk, sc, new byte[256], sb, sb.Capacity, 0, hkl);
        if (!isDeadKey && rc == -1) isDeadKey = true;
        Console.Write(rc);
    }
    return isDeadKey;
}

在您的代码中执行ToUnicodeEx&#39;:

var isDeadKey = ClearKeyboardBuffer((uint)aKey, 0, hKd);
if (isDeadKey) return;
user32.ToUnicodeEx((uint)aKey, vkCode, keyboardState, characters, 10, (uint)0, hKd);

参考: http://www.siao2.com/2006/03/23/558658.aspx http://www.siao2.com/2006/04/06/569632.aspx

还看看他的代码: https://stackoverflow.com/a/8705696/802848