问题描述
我已经浏览了几个关于此的早期问题,到目前为止我找到的最佳答案是这样的:
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
我似乎总是得到字符 -
,即使当前的键盘布局是德语,我希望这个键返回 ß
.
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.
这篇关于如何根据当前键盘布局将虚拟键代码转换为字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!