代表当前文化中的特殊键盘键?

时间:2015-07-01 07:03:21

标签: c# .net vb.net keyboard raw-input

方案

我使用现代 RawInput 技术编写了一个简单的键盘记录程序,用于为事件/数据拦截注册所需的设备。

然后,我基本上使用了所有这些 Windows API 成员定义:

问题/疑问

我正在使用非英语 OS 的非英语键盘,然后,当我尝试解析此键盘的特殊键时,我的问题就开始了,就像ñ / Ñ字符被识别为System.Windows.Forms.Keys.OemTilde键, 或ç / Ç字符,该字符被识别为System.Windows.Forms.Keys.OemQuestion键。

我想让我的键盘记录器特定于语言识别(至少,对我目前的文化有正确的字符识别, es-ES ),但我因为缺乏知识而陷入困境开始正确检索那些字符。

请注意,我的目的是学习当我按下Ñ字符时,我可以用有效/自动的方式来执行此操作,例如 OS 对我的键盘执行操作它键入Ñ,我的意思是我完全了解一个解决方案,意味着执行特殊字符的手动解析,例如:

Select Case MyKey

    Case Keys.OemTilde
        char = "ñ"c

End Select

这不是我正在寻找的行为,但我可以理解,也许我需要额外的“事物”来重现每种keayborad的那些字符的良好识别/翻译,但我需要什么“东西” ?

研究

我不知道如何继续,因为正如我所说,我没有知识来知道这个问题的答案(这就是我要问的原因),但我想象当前键盘的知识布局将涉及,然后,我知道我可以使用CultureInfo.CurrentCulture.KeyboardLayoutId属性检索当前的键盘布局。

我知道 en-US 的文化键盘布局 1033 ,而文化 es-ES 的键盘布局 3082 < /强>

另外,请注意MakeCode结构的RAWKEYBOARD成员的文档,也许这似乎暗示了我假装做的事情,我不知道:

  

MakeCode

     

输入:USHORT

     

键按下的扫描码。   键盘超限的扫描码是KEYBOARD_OVERRUN_MAKE_CODE。

1 个答案:

答案 0 :(得分:2)

但实际上这是猜测工作 这是我找到的代码。

正确的解决方案是ToUnicode WinAPI功能:

[DllImport("user32.dll")]
public static extern int ToUnicode(uint virtualKeyCode, uint scanCode,
    byte[] keyboardState,
    [Out, MarshalAs(UnmanagedType.LPWStr, SizeConst = 64)]
    StringBuilder receivingBuffer,
    int bufferSize, uint flags);



static string GetCharsFromKeys(Keys keys, bool shift, bool altGr)
{
    var buf = new StringBuilder(256);
    var keyboardState = new byte[256];
    if (shift)
        keyboardState[(int) Keys.ShiftKey] = 0xff;
    if (altGr)
    {
        keyboardState[(int) Keys.ControlKey] = 0xff;
        keyboardState[(int) Keys.Menu] = 0xff;
    }
    WinAPI.ToUnicode((uint) keys, 0, keyboardState, buf, 256, 0);
    return buf.ToString();
}


Console.WriteLine(GetCharsFromKeys(Keys.E, false, false));    // prints e
Console.WriteLine(GetCharsFromKeys(Keys.E, true, false));     // prints E

// Assuming British keyboard layout:
Console.WriteLine(GetCharsFromKeys(Keys.E, false, true));     // prints é
Console.WriteLine(GetCharsFromKeys(Keys.E, true, true));      // prints É