我已经浏览了几个关于这个的早期问题,到目前为止我找到的最佳答案是这样的:
(char) WinAPI.MapVirtualKey((uint) Keys.A, 2)
但是,这在两种情况下不起作用:
它总是返回大写字母。对于
Keys.A
我希望得到字符a
,而对于Keys.A | Keys.ShiftKey
我希望得到A
;但是,我似乎都得到了A
。它似乎没有考虑键盘布局。例如,对于
Keys.OemMinus
,我似乎总是得到字符-
,即使当前键盘布局是德语,我希望此键返回ß
.
正确的解决方案是什么?
最佳答案
正确的解决方案是 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 É
也可以使用 ToUnicodeEx
检索不是当前事件键盘布局的字符。签名是相同的,除了一个额外的参数,即输入语言环境 ID,可以使用 LoadKeyboardLayout
检索它。功能。
关于c# - 如何根据当前键盘布局将虚拟键码转换为字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6929275/