Как преобразовать символ в эквивалентное значение перечисления System.Windows.Input.Key? - PullRequest
16 голосов
/ 13 февраля 2009

Я хочу написать такую ​​функцию,

        public System.Windows.Input.Key ResolveKey(char charToResolve)
        {
            // Code goes here, that resolves the charToResolve
            // in to the Key enumerated value
            // (For example with '.' as the character for Key.OemPeriod)

        }

Я знаю, что могу написать огромный футляр для коммутатора, соответствующий персонажу, но есть ли другой способ? С этим связано то, что строка перечисления Key может не совпадать с символом, поэтому Enum.IsDefined не будет работать

Есть идеи?

Обновление: это в среде Windows

Ответы [ 4 ]

25 голосов
/ 13 февраля 2009
[DllImport("user32.dll")]
static extern short VkKeyScan(char ch);

static public Key ResolveKey(char charToResolve)
{
    return KeyInterop.KeyFromVirtualKey(VkKeyScan(charToResolve));
}
7 голосов
/ 13 февраля 2009

Попробуйте использовать метод ConvertFrom класса System.Windows.Input.KeyConverter.

1 голос
/ 30 января 2016

Недавно я нашел отличный ответ на аналогичный вопрос от Джона Ханны , который также может обрабатывать состояния клавиш управления:

Этот пример легче объяснить с помощью примера программы, чем что-нибудь еще:

namespace KeyFinder
{
  class Program
  {
    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    static extern short VkKeyScanEx(char ch, IntPtr dwhkl);
    [DllImport("user32.dll")]
    static extern bool UnloadKeyboardLayout(IntPtr hkl);
    [DllImport("user32.dll")]
    static extern IntPtr LoadKeyboardLayout(string pwszKLID, uint Flags);
    public class KeyboardPointer : IDisposable
    {
      private readonly IntPtr pointer;
      public KeyboardPointer(int klid)
      {
        pointer = LoadKeyboardLayout(klid.ToString("X8"), 1);
      }
      public KeyboardPointer(CultureInfo culture)
        :this(culture.KeyboardLayoutId){}
      public void Dispose()
      {
        UnloadKeyboardLayout(pointer);
        GC.SuppressFinalize(this);
      }
      ~KeyboardPointer()
      {
        UnloadKeyboardLayout(pointer);
      }
      // Converting to System.Windows.Forms.Key here, but
      // some other enumerations for similar tasks have the same
      // one-to-one mapping to the underlying Windows API values
      public bool GetKey(char character, out Keys key)
      {
        short keyNumber = VkKeyScanEx(character, pointer);
        if(keyNumber == -1)
        {
          key = System.Windows.Forms.Keys.None;
          return false;
        }
        key = (System.Windows.Forms.Keys)(((keyNumber & 0xFF00) << 8) | (keyNumber & 0xFF));
        return true;
      }
    }
    private static string DescribeKey(Keys key)
    {
      StringBuilder desc = new StringBuilder();
      if((key & Keys.Shift) != Keys.None)
        desc.Append("Shift: ");
      if((key & Keys.Control) != Keys.None)
        desc.Append("Control: ");
      if((key & Keys.Alt) != Keys.None)
        desc.Append("Alt: ");
      return desc.Append(key & Keys.KeyCode).ToString();
    }
    public static void Main(string[] args)
    {
      string testChars = "Aéש";
      Keys key;
      foreach(var culture in (new string[]{"he-IL", "en-US", "en-IE"}).Select(code => CultureInfo.GetCultureInfo(code)))
      {
        Console.WriteLine(culture.Name);
        using(var keyboard = new KeyboardPointer(culture))
          foreach(char test in testChars)
          {
            Console.Write(test);
            Console.Write('\t');
            if(keyboard.GetKey(test, out key))
              Console.WriteLine(DescribeKey(key));
            else
              Console.WriteLine("No Key");
          }
      }
      Console.Read();//Stop window closing
    }
  }
}

Выход:

he-IL
A  Shift: A
é  No Key
ש  A
en-US
A  Shift: A
é  No Key
ש  No Key
en-IE
A  Shift: A
é  Control: Alt: E
ש  No Key

(Хотя ваша собственная консоль может испортить ש и / или é в зависимости от настройки и шрифты).

Прочитать полное описание от ссылочного ответа

1 голос
/ 23 декабря 2011

Привет Просто конвертируйте таким образом

Dim KeyConverter As New Forms.KeysConverter    
Dim S As String = KeyConverter.ConvertToString(e.Key)
Dim O As System.Windows.Forms.Keys = KeyConverter.ConvertFrom(S)
Dim ChValue As Integer = CType(O, Integer) 

В моем случае я нажимаю «ENTER» на моей клавиатуре, O переходит в ENTER {13} и ChValue переходит в код символа 13 Например, для ключа TAB я получу код символа 9.

...