how to capture the '#' character on different locale keyboards in WPF/C#?

前端 未结 2 1066
既然无缘
既然无缘 2020-11-27 05:02

My WPF application handles keyboard presses and specifically the # and * character as it is a VoIP phone.

I have a bug though with international keyboards, and in pa

相关标签:
2条回答
  • 2020-11-27 05:35

    I found a helpful solution in this post: http://www.codewrecks.com/blog/index.php/2008/05/06/wpf-convert-systemwindowsinputkey-to-char-or-string-2/

    There is another event TextInput or PreviewTextInput which gives the character as string instead of the Key :).

    0 讨论(0)
  • 2020-11-27 05:44

    The function below, GetCharFromKey(Key key) will do the trick.

    It uses a series of win32 calls to decode the key pressed:

    1. get the virtual key from WPF key

    2. get the scan code from the virtual key

    3. get your unicode character

    This old post describes it in a bit more detail.

          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 讨论(0)
提交回复
热议问题