【问题标题】:how to capture the '#' character on different locale keyboards in WPF/C#?如何在 WPF/C# 的不同语言环境键盘上捕获“#”字符?
【发布时间】:2011-08-15 02:41:30
【问题描述】:

我的 WPF 应用程序处理键盘按下,特别是 # 和 * 字符,因为它是 VoIP 电话。

我在使用国际键盘时遇到了一个错误,尤其是英式英语键盘。通常我会听 3 键,如果按下 shift 键修饰符,我们会触发一个事件来做一些事情。然而,在英式键盘上,这是“£”字符。我发现英国英语键盘有一个专用的“#”键。显然,我们可以只听那个特定的键,但这并不能解决美国英语的情况,即 shift-3 以及将它放在其他地方的无数其他键盘。

长话短说,我如何从按键中听到特定字符(无论是组合键还是单键)并对其做出反应?

【问题讨论】:

    标签: c# wpf keypress


    【解决方案1】:

    下面的函数 GetCharFromKey(Key key) 可以解决问题。

    它使用一系列 win32 调用来解码按下的键:

    1. 获取virtual key from WPF key

    2. 获取scan code from the virtual key

    3. 获取your unicode character

    old post 更详细地描述了它。

          public enum MapType : uint
          {
             MAPVK_VK_TO_VSC = 0x0,
             MAPVK_VSC_TO_VK = 0x1,
             MAPVK_VK_TO_CHAR = 0x2,
             MAPVK_VSC_TO_VK_EX = 0x3,
          }
    
          [DllImport("user32.dll")]
          public static extern int ToUnicode(
              uint wVirtKey,
              uint wScanCode,
              byte[] lpKeyState,
              [Out, MarshalAs(UnmanagedType.LPWStr, SizeParamIndex = 4)] 
                StringBuilder pwszBuff,
              int cchBuff,
              uint wFlags);
    
          [DllImport("user32.dll")]
          public static extern bool GetKeyboardState(byte[] lpKeyState);
    
          [DllImport("user32.dll")]
          public static extern uint MapVirtualKey(uint uCode, MapType uMapType);
    
          public static char GetCharFromKey(Key key)
          {
             char ch = ' ';
    
             int virtualKey = KeyInterop.VirtualKeyFromKey(key);
             byte[] keyboardState = new byte[256];
             GetKeyboardState(keyboardState);
    
             uint scanCode = MapVirtualKey((uint)virtualKey, MapType.MAPVK_VK_TO_VSC);
             StringBuilder stringBuilder = new StringBuilder(2);
    
             int result = ToUnicode((uint)virtualKey, scanCode, keyboardState, stringBuilder, stringBuilder.Capacity, 0);
             switch (result)
             {
                case -1: 
                   break;
                case 0: 
                   break;
                case 1:
                   {
                      ch = stringBuilder[0];
                      break;
                   }
                default:
                   {
                      ch = stringBuilder[0];
                      break;
                   }
             }
             return ch;
          }
    

    【讨论】:

    • 对于不产生文本字符的键,它确实应该返回'\0',或者返回(char?)null
    • 之前提到的“旧帖”已经不见了,但仍然可以在这里访问:web.archive.org/web/20111229040043/http://huddledmasses.org/…
    • 备案,WinForms版本为here
    • 它需要引用组装WindowsBase然后使用System.Windows.Input;
    • 有人把这个放在 NuGet 包里吗?
    【解决方案2】:

    我在这篇文章中找到了一个有用的解决方案:http://www.codewrecks.com/blog/index.php/2008/05/06/wpf-convert-systemwindowsinputkey-to-char-or-string-2/

    还有另一个事件 TextInputPreviewTextInput 将字符作为字符串而不是 Key :)。

    【讨论】:

      猜你喜欢
      • 2016-06-21
      • 2012-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多