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

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

问题描述

我已经浏览了几个关于此的早期问题,到目前为止我找到的最佳答案是这样的:

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 我似乎总是得到字符 -,即使当前的键盘布局是德语,我希望这个键返回 ß.

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 is also possible to use ToUnicodeEx to retrieve the characters for a keyboard layout that is not the currently active one. The signature is the same except for one extra parameter, the input locale ID, which can be retrieved using the LoadKeyboardLayout function.

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

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