2013-12-13 4 views
2

나는 char을 읽고 그것의 언어와 키보드 레이아웃과 관련된 Key를 얻을 수 있어야한다.char에서 KeyCode를 가져 옵니까?

나는 문화적인 배경과 언어를 보는 법을 알고있다. 하지만 어떻게 영어로 'S'와 같은 편지를 받아 키보드에서 어떤 키인지 알 수 있습니까? 더 어려운 문제에 대해서는 어떻게 문자 'ש'를 가져와 키보드의 어떤 키인지 알 수 있습니까?

+0

@ Liam, 요청이 있으면 이유가 있어야합니다 ... – serhio

+2

하지만 @serhio, 우리가 추론을 알고 있다면 아마도 더 논리적 인 해결책이 될 것입니다. – Liam

+1

하나의 키가 아닌 여러 개의 키에 해당하는 많은 기호가 있습니다. 예를 들어 대거 (†) 기호는 Alt 0134 \t \t (http://www.forlang.wsu.edu/help/keyboards.asp 참조) 조합을 사용하여 얻을 수 있으므로 논리적 인 해결책이없는 것 같습니다. – serhio

답변

11
이 하나 더 쉽게 무엇보다 예제 프로그램 설명 될 수

:

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 

(자신의 콘솔 힘 엉망 ש 및/또는 é에 따라 비록 설정 및 글꼴).

키보드에 AltGr 키가없는 경우 대신 Ctrl + Alt를 사용하는 Windows kludge는 정확하게보고되는 방식이며 두 가지가 별도로 처리된다는 것을 다시 한 번 강조합니다 Windows 키보드의 유연성이 떨어지는 것들 (Alt + AltGr은 Windows에서는 의미가 없습니다).

편집 : CultureInfo을 사용하는 KeyboardPointer의 생성자는 명백하게 사용하기 쉽지만 숫자를 사용하는 생성자는 주어진 문화권의 보조 키보드에 유용합니다. 예 : en-US는 가장 자주 0x0149를 사용하지만 Dvorak와 같은 변형 레이아웃, 문자에 대한 확장 지원 (영어를 작성하는 데 필요한 "국제 미국")과 같이 다른 상위 단어 (0x00010149, 0x00020149, 0x00030149 등)가있는 변형이 있습니다. "naïve", "façade"또는 "résumé"와 같은 단어) 등이 있습니다.

+0

아주 좋은 대답입니다. 고맙습니다. –

0

KeyCode을 구문 분석하여 검색중인 문자가 포함되어 있는지 확인할 수 있습니다. 영어 이외의 입력에 대해서는 키보드에서 어떤 키인지를 알기 위해 영어 문자를 매핑해야합니다.

+1

키보드를 아는 경우를 제외하고는 KeyCode에서 문자를 추론 할 수 없습니다. –

관련 문제