代表当前文化中的一个特殊键盘键
本文关键字:一个 键盘 文化中 | 更新日期: 2023-09-27 18:00:39
场景
我使用现代RawInput技术编写了一个简单的键盘记录程序,注册所需的设备进行事件/数据拦截。
- 关于原始输入
然后,我基本上使用所有这些Windows API成员定义:
- 原始输入函数
- 原始输入结构
问题/问题
我用的是一个非英语键盘和一个非英文的O。S,那么,当我试图解析这个键盘的一个特殊键时,我的问题就开始了,比如被识别为System.Windows.Forms.Keys.OemTilde
键的ñ/nie字符,或被识别为System.Windows.Forms.Keys.OemQuestion
密钥的ç/Ç字符。
我想让我的键盘记录程序的语言特定(或者至少,对我当前的文化有适当的字符识别,es es),但我被卡住了,因为我缺乏开始正确检索这些字符的知识。
请注意,我的意图是学习如何像O那样以高效/自动化的方式完成这项工作。当我按下ñ字符时,S会对我的键盘进行操作,它会键入ã 这不是我想要的行为,但我可以理解,也许我需要额外的"东西"来为每种keayborad复制这些字符的良好识别/翻译,但我需要什么"东西"?。 我不知道如何继续,因为正如我所说,我不知道这个问题的答案(这就是我问的原因),但我想会涉及到当前键盘布局的知识,然后,我知道我可以用 我知道文化en-US的键盘布局是1033,而文化es es是3082。 另外,请注意 MakeCode 型号:USHORT 按下按键后的扫描代码。键盘超限的扫描代码为keyboard_overrun_MAKE_code。Select Case MyKey
Case Keys.OemTilde
char = "ñ"c
End Select
研究
CultureInfo.CurrentCulture.KeyboardLayoutId
属性检索当前键盘布局。RAWKEYBOARD
结构的MakeCode
成员的文档,也许这似乎是我假装做什么的提示,我不知道:
但实际上这是一项猜测工作这是我找到的代码。
正确的解决方案是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 É