我使用现代 RawInput 技术编写了一个简单的键盘记录程序,用于为事件/数据拦截注册所需的设备。
然后,我基本上使用了所有这些 Windows API 成员定义:
我正在使用非英语 OS 的非英语键盘,然后,当我尝试解析此键盘的特殊键时,我的问题就开始了,就像ñ / Ñ字符被识别为System.Windows.Forms.Keys.OemTilde
键,
或ç / Ç字符,该字符被识别为System.Windows.Forms.Keys.OemQuestion
键。
我想让我的键盘记录器特定于语言识别(至少,对我目前的文化有正确的字符识别, es-ES ),但我因为缺乏知识而陷入困境开始正确检索那些字符。
请注意,我的目的是学习当我按下Ñ字符时,我可以用有效/自动的方式来执行此操作,例如 OS 对我的键盘执行操作它键入Ñ,我的意思是我完全了解一个解决方案,意味着执行特殊字符的手动解析,例如:
Select Case MyKey
Case Keys.OemTilde
char = "ñ"c
End Select
这不是我正在寻找的行为,但我可以理解,也许我需要额外的“事物”来重现每种keayborad的那些字符的良好识别/翻译,但我需要什么“东西” ?
我不知道如何继续,因为正如我所说,我没有知识来知道这个问题的答案(这就是我要问的原因),但我想象当前键盘的知识布局将涉及,然后,我知道我可以使用CultureInfo.CurrentCulture.KeyboardLayoutId
属性检索当前的键盘布局。
我知道 en-US 的文化键盘布局 1033 ,而文化 es-ES 的键盘布局 3082 < /强>
另外,请注意MakeCode
结构的RAWKEYBOARD
成员的文档,也许这似乎暗示了我假装做的事情,我不知道:
MakeCode
输入:USHORT
键按下的扫描码。 键盘超限的扫描码是KEYBOARD_OVERRUN_MAKE_CODE。
答案 0 :(得分:2)
但实际上这是猜测工作 这是我找到的代码。
正确的解决方案是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 É