Soru WPF / C # içindeki farklı yerel klavyelerde '#' karakterini nasıl yakalayabiliriz?


WPF uygulamam, klavye preslerini ve özellikle de # ve * karakterini bir VoIP telefon olarak ele alır.

Uluslararası klavye ve özellikle İngiliz ingilizce klavye ile bir hata var. Normalde 3 anahtarını dinlerim ve vardiya anahtar değiştiricisi aşağıdaysa, bir şeyler yapmak için bir olayı başlatırız. Ancak İngiliz klavyesinde bu '£' karakteridir. İngiltere ingilizce klavyesinin '#' için özel bir anahtarı olduğunu gördüm. Belli ki, sadece bu anahtarı dinleyebiliriz, fakat bu durum, İngilizcenin vardiya-3 ve başka bir yere koyan sayısız diğer klavyenin durumunu çözmez.

Uzun lafın kısası, anahtar bir tuştan belirli bir karakteri nasıl dinleyebilirim, ister anahtar birleşik ister tek bir anahtar olsun ve buna tepki veriyor mu?


25
2018-04-28 22:34


Menşei




Cevaplar:


Aşağıdaki işlev, GetCharFromKey (Anahtar tuşu) hile yapacaktır.

Basılan tuşun kodunu çözmek için bir dizi win32 araması kullanır:

  1. almak WPF anahtarından sanal anahtar

  2. almak sanal anahtardan tarama kodu

  3. almak senin unicode karakterin

Bu eski yazı biraz daha ayrıntılı olarak açıklar.

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

53
2018-04-28 23:19



Bunu bir süredir kullanıyorum ve bir hatayı fark ettim. Aynı sonucu GetCharFromKey'den dönen iki anahtar. Doğrulamak için, sadece bir TextBox alt sınıfı, PreiewKeyDown'ı geçersiz kılın, boşluk çubuğuna vurun, (32 karakterlik), sonra Delete tuşuna basın, ayrıca 32 karakter döndürür. Bunu gören başka biri var mı? - gcadmes
Peki bu humbling oldu ... GetCharFromKey ilk ifadesi char ch = ''; Yani '0' veya '1' içine düşen durumlarda, dönüş char her zaman bir boşluk (char) 32 idi. (alın tokatı) - gcadmes
Gerçekten dönmeli '\0' Metin karakteri oluşturmayan tuşlar için veya (char?)null. - jnm2
@George silverlight hakkında ne dersiniz? - rr-
Bahsedilen "eski posta" şimdi gitti, ancak yine de buradan erişilebilir: web.archive.org/web/20111229040043/http://huddledmasses.org/.... - Olly