나는 char을 읽고 그것의 언어와 키보드 레이아웃과 관련된 Key를 얻을 수 있어야한다.char에서 KeyCode를 가져 옵니까?
나는 문화적인 배경과 언어를 보는 법을 알고있다. 하지만 어떻게 영어로 'S'와 같은 편지를 받아 키보드에서 어떤 키인지 알 수 있습니까? 더 어려운 문제에 대해서는 어떻게 문자 'ש'를 가져와 키보드의 어떤 키인지 알 수 있습니까?
나는 char을 읽고 그것의 언어와 키보드 레이아웃과 관련된 Key를 얻을 수 있어야한다.char에서 KeyCode를 가져 옵니까?
나는 문화적인 배경과 언어를 보는 법을 알고있다. 하지만 어떻게 영어로 'S'와 같은 편지를 받아 키보드에서 어떤 키인지 알 수 있습니까? 더 어려운 문제에 대해서는 어떻게 문자 'ש'를 가져와 키보드의 어떤 키인지 알 수 있습니까?
:
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é"와 같은 단어) 등이 있습니다.
아주 좋은 대답입니다. 고맙습니다. –
KeyCode을 구문 분석하여 검색중인 문자가 포함되어 있는지 확인할 수 있습니다. 영어 이외의 입력에 대해서는 키보드에서 어떤 키인지를 알기 위해 영어 문자를 매핑해야합니다.
키보드를 아는 경우를 제외하고는 KeyCode에서 문자를 추론 할 수 없습니다. –
@ Liam, 요청이 있으면 이유가 있어야합니다 ... – serhio
하지만 @serhio, 우리가 추론을 알고 있다면 아마도 더 논리적 인 해결책이 될 것입니다. – Liam
하나의 키가 아닌 여러 개의 키에 해당하는 많은 기호가 있습니다. 예를 들어 대거 (†) 기호는 Alt 0134 \t \t (http://www.forlang.wsu.edu/help/keyboards.asp 참조) 조합을 사용하여 얻을 수 있으므로 논리적 인 해결책이없는 것 같습니다. – serhio