2009-02-13 2 views
15

Я хочу, чтобы написать функцию, как это так,Как преобразовать символ в эквивалентное значение System.Windows.Input.Key Enum?

 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) 

     } 

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

Любые идеи?

Update: Это в среде Windows,

+0

Что такое окружающая среда? WinForms/asp.net? Какова цель этого? – shahkalpesh

ответ

23
[DllImport("user32.dll")] 
static extern short VkKeyScan(char ch); 

static public Key ResolveKey(char charToResolve) 
{ 
    return KeyInterop.KeyFromVirtualKey(VkKeyScan(charToResolve)); 
}
+1

'VkKeyScan()' использует старший байт для кодирования состояний ключа-модификатора, так что это не выполняется для прописных букв, потому что 'VkKeyScan()' добавляет в флаг сдвига. Если вы и возвращаемое значение 'VkKeyScan()' с '0xFF' очистите эти флаги, оно будет работать с заглавными буквами. – shf301

7

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

+0

не работает с '.' – Avram

+0

Это не предназначено для использования таким образом. Взгляните на него в Reflector, и вы увидите, что он поддерживает только буквы, цифры и несколько других клавиш. Известные исключения включают?, Которые должны быть строкой «OemQuestion», чтобы правильно преобразовать. – OwenP

1

Привет Просто преобразовать таким образом

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 собирается в Character кодекс 13 Для TAB Key я буду получите код персонажа 9 таким образом, например.

1

Недавно я нашел отличный answer for similar question from Jon Hanna, который может обрабатывать управляющие ключевые государства, а также:

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

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 

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

Читать полное описание от referenced answer

Смежные вопросы