web-dev-qa-db-fra.com

Comment capturer le caractère '#' sur différents claviers locaux dans WPF / C #?

Mon application WPF gère des presses clavier et spécifiquement le caractère # et * car il s'agit d'un téléphone VoIP.

J'ai un bug avec des claviers internationaux, et en particulier le clavier anglais britannique. Normalement, j'écoute pour la clé 3 et si le modificateur de touche Maj est en bas, nous tirons un événement pour faire des choses. Cependant sur le clavier britannique, il s'agit du personnage "£". J'ai trouvé que le clavier anglais britannique a une clé dédiée pour "#". Évidemment, nous pourrions simplement écouter cette clé particulière, mais cela ne résout pas le cas pour nous anglais qui est Maj d'autres claviers et tous les innombrables autres claviers qui la mettent ailleurs.

Longue histoire courte, comment puis-je écouter un caractère particulier à partir d'une touche appuyez sur une touche clé ou une touche unique et réagissez-y?

30
Jippers

La fonction ci-dessous, GetcharFromkey (touche clé) fera le tour.

Il utilise une série d'appels Win32 pour décoder la clé pressée:

  1. obtenez la Touche virtuelle de la clé WPF

  2. obtenez le code de numérisation de la clé virtuelle

  3. obtenez votre personnage Unicode

Ceci Old Post le décrit dans un peu plus de détails.

      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;
      }
55
George