如何根据当前的键盘布局的虚拟键码转换成一个字符? [英] How to convert a virtual-key code to a character according to the current keyboard layout?

查看:355
本文介绍了如何根据当前的键盘布局的虚拟键码转换成一个字符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经浏览一下这几款前面的问题,最好的答案,我发现到目前为止是这样的:

I have browsed several earlier questions about this, and the best answer I found so far is something like this:

(char) WinAPI.MapVirtualKey((uint) Keys.A, 2)

然而,这并不在两方面的工作:

However, this doesn't work in two ways:


  • 它总是返回大写字母。对于 Keys.A 我期望得到的字符 A ,而 Keys.A | Keys.ShiftKey 我期望能获得 A ;不过,我似乎得到 A

  • It always returns capital letters. For Keys.A I expect to get the character a, while for Keys.A | Keys.ShiftKey I expect to get A; however, I seem to get A for both.

这似乎并没有采取键盘布局考虑。例如, Keys.OemMinus 我似乎总是得到字符 - ,即使当前的键盘布局是德国人,在这里我希望这个键返回 SS

It doesn't seem to take keyboard layouts into account. For example, for Keys.OemMinus I always seem to get the character -, even if the current keyboard layout is German, where I expect this key to return ß.

什么是这个正确的解决方案?

What is the correct solution for this?

推荐答案

正确的解决办法是 ToUnicode WinAPI的功能:

The correct solution is the ToUnicode WinAPI function:

[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);

要包装成一个明智的,方便的方法,这将是一个方法:

One way to wrap this into a sensible, convenient method would be:

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();
}

现在,我们可以检索字符和实际得到预期的结果:

Now we can retrieve characters and actually get the expected results:

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 É



另外,也可以使用 ToUnicodeEx 检索键盘布局中的字符不是当前活动之一。签名是除了一个额外的参数,输入区域设置ID,可以使用的 LoadKeyboardLayout 功能。

这篇关于如何根据当前的键盘布局的虚拟键码转换成一个字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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