如何在WPF/C#中的不同语言环境键盘上捕获'#'字符?

Jip*_*ers 29 c# wpf keypress

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

我有一个国际键盘,特别是英国英语键盘的错误.通常我会听3键,如果shift键修改器关闭,我们会触发一个事件来做事情.然而在英国键盘上,这是'£'字符.我发现英国英语键盘有一个专用的'#'键.显然我们可以只听那个特定的键,但这并不能解决美国英语的问题,即shift-3和所有无数其他键盘都把它放在其他地方.

简而言之,我如何通过按键来聆听特定角色,无论是关键组合还是单键并对其作出反应?

Geo*_*rge 57

下面的函数GetCharFromKey(Key key)将起到作用.

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

  1. 从WPF密钥获取虚拟密钥

  2. 从虚拟密钥中获取扫描代码

  3. 得到你的unicode角色

这篇老帖子更详细地描述了它.

      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;
      }
Run Code Online (Sandbox Code Playgroud)

  • 对于不产生文本字符的键或`(char?)null`,它应该返回''\ 0'`. (3认同)
  • 提到的"旧帖子"现已消失,但仍可在此访问:http://web.archive.org/web/20111229040043/http://huddledmasses.org/how-to-get-the-character-and -virtualkey-从-A-WPF-的keydown事件. (2认同)
  • 为了记录,WinForms 版本是[这里](http://stackoverflow.com/a/38787314/568266) (2认同)
  • 有人把它放在NuGet包中吗? (2认同)