如何根据当前的键盘布局的虚拟键码转换成一个字符? [英] How to convert a virtual-key code to a character according to the current keyboard layout?
问题描述
我已经浏览一下这几款前面的问题,最好的答案,我发现到目前为止是这样的:
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 charactera
, while forKeys.A | Keys.ShiftKey
I expect to getA
; however, I seem to getA
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屋!