C#如何翻译虚拟键码字符?

我正在尝试将虚拟键码映射到字符。

我的代码使用ProcessCmdKey来监听WM_KEYDOWN,这使我可以访问按下的键。 例如,当我按单引号,我得到一个222的关键,我想它映射到keychar 39代表…你猜对了…单引号。

我的开发环境是:.net Framework 2.0 – UserControl放置在很多地方

你知道这个问题的答案吗?

这不是什么System.Windows.Form.KeysConverter类是什么?

KeysConverter kc = new KeysConverter(); string keyChar = kc.ConvertToString(keyData); 

是的,我确实使用了MapVirtualKey方法。 但是我期待更多关于如何使用它的细节:使用什么DllImport指令,哪些enum是特定于映射到字符等等。

我不喜欢这些答案,你的谷歌5秒钟,然后只是build议一个解决scheme:真正的挑战是把所有的作品拼凑在一起,而不必浪费你的时间与大量的无样品的MSDN页面或其他编码论坛为了得到你的答案。 没有犯法的基础,但是你的回答(甚至是好的)是没有问题的,因为我甚至在论坛上发表我的问题之前就已经有了这个答案!

所以,你去,我要发布我正在寻找的 – 一个开箱即用的C#解决scheme:

1-把这个指令放在你的类中:

 [DllImport("user32.dll")] static extern int MapVirtualKey(uint uCode, uint uMapType); 

2-像这样检索你的字符:

  protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { const int WM_KEYDOWN = 0x100; if (msg.Msg == WM_KEYDOWN) { // 2 is used to translate into an unshifted character value int nonVirtualKey = MapVirtualKey((uint)keyData, 2); char mappedChar = Convert.ToChar(nonVirtualKey); } return base.ProcessCmdKey(ref msg, keyData); } 

谢谢关心…并享受!

在阅读和testing了一些提供的答案后,我想我会build议一个替代scheme。

正如MM所提到的,System.Windows.KeysConverter不提供键的字符表示,而是提供枚举的名称,例如“Enter”而不是“\ n”。

Horas提出的MapVirtualKey方法在回答他自己的问题时是一个很好的起点,但是仍然不支持大写字母或用shift键input的字符,例如'!','$'和'>'。

我正在使用的MapVirtualKey方法的替代方法是Keys类的扩展方法:

 public static char ToChar(this Keys key) { char c = '\0'; if((key >= Keys.A) && (key <= Keys.Z)) { c = (char)((int)'a' + (int)(key - Keys.A)); } else if((key >= Keys.D0) && (key <= Keys.D9)) { c = (char)((int)'0' + (int)(key - Keys.D0)); } return c; } 

上面显示的方法将提供对字母数字字符的支持。 支持额外的字符可以用switch语句或查找表来实现。

我正在寻找类似的东西,但我需要映射到当前键盘布局的字符。 由于上述答案都不符合我的要求,所以我想到了这一点。

 public string KeyCodeToUnicode(Keys key) { byte[] keyboardState = new byte[255]; bool keyboardStateStatus = GetKeyboardState(keyboardState); if (!keyboardStateStatus) { return ""; } uint virtualKeyCode = (uint)key; uint scanCode = MapVirtualKey(virtualKeyCode, 0); IntPtr inputLocaleIdentifier = GetKeyboardLayout(0); StringBuilder result = new StringBuilder(); ToUnicodeEx(virtualKeyCode, scanCode, keyboardState, result, (int)5, (uint)0, inputLocaleIdentifier); return result.ToString(); } [DllImport("user32.dll")] static extern bool GetKeyboardState(byte[] lpKeyState); [DllImport("user32.dll")] static extern uint MapVirtualKey(uint uCode, uint uMapType); [DllImport("user32.dll")] static extern IntPtr GetKeyboardLayout(uint idThread); [DllImport("user32.dll")] static extern int ToUnicodeEx(uint wVirtKey, uint wScanCode, byte[] lpKeyState, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszBuff, int cchBuff, uint wFlags, IntPtr dwhkl); 

KeysConverter得到的关键名称不是关键字“text”ex:“Num2”而不是“2”MapVirtualKey将适用于英文,但对于非英文字符文档状态使用MapVirtualKeyEx但需要一个区域标识符,该标识符由LoadKeyBoardLayout加载,一个文化编号不变,但后来find正确的身份证号码,它不工作,因为我试了一下,所以最后我倾倒了整个事情

我刚写了一个Ivan Petrov的改进回答,以显示在WPF中按下组合键的string表示forms,请参阅下面的代码:

 public static string GetKeyString(Key key, ModifierKeys modifiers) { string result = ""; if (key != Key.None) { // Setup modifiers if (modifiers.HasFlag(ModifierKeys.Control)) result += "Ctrl + "; if (modifiers.HasFlag(ModifierKeys.Alt)) result += "Alt + "; if (modifiers.HasFlag(ModifierKeys.Shift)) result += "Shift + "; // Get string representation string keyStr = key.ToString(); int keyInt = (int)key; // Numeric keys are returned without the 'D' if (key >= Key.D0 && key <= Key.D9) keyStr = char.ToString((char)(key - Key.D0 + '0')); // Char keys are returned directly else if (key >= Key.A && key <= Key.Z) keyStr = char.ToString((char)(key - Key.A + 'A')); // If the key is a keypad operation (Add, Multiply, ...) or an 'Oem' key, P/Invoke else if ((keyInt >= 84 && keyInt <= 89) || keyInt >= 140) keyStr = KeyCodeToUnicode(key); result += keyStr; } return result; } private static string KeyCodeToUnicode(Key key) { byte[] keyboardState = new byte[255]; bool keyboardStateStatus = GetKeyboardState(keyboardState); if (!keyboardStateStatus) { return ""; } uint virtualKeyCode = (uint)KeyInterop.VirtualKeyFromKey(key); uint scanCode = MapVirtualKey(virtualKeyCode, 0); IntPtr inputLocaleIdentifier = GetKeyboardLayout(0); StringBuilder result = new StringBuilder(); ToUnicodeEx(virtualKeyCode, scanCode, new byte[255], result, (int)5, (uint)0, inputLocaleIdentifier); return result.ToString(); } [DllImport("user32.dll")] static extern bool GetKeyboardState(byte[] lpKeyState); [DllImport("user32.dll")] static extern uint MapVirtualKey(uint uCode, uint uMapType); [DllImport("user32.dll")] static extern IntPtr GetKeyboardLayout(uint idThread); [DllImport("user32.dll")] static extern int ToUnicodeEx(uint wVirtKey, uint wScanCode, byte[] lpKeyState, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszBuff, int cchBuff, uint wFlags, IntPtr dwhkl);