I want to write a function like so,
我想写一个这样的函数,
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)
}
I know I can write a huge Switch-case to match the character, but is there any other way? The thing with this is the Key enum's string may not match with the character so Enum.IsDefined will not work
我知道我可以写一个巨大的Switch-case来匹配角色,但还有其他方法吗?这个问题是Key枚举的字符串可能与字符不匹配,因此Enum.IsDefined不起作用
Any ideas?
Update: This is in Windows environment
更新:这是在Windows环境中
4 个解决方案
#1
23
[DllImport("user32.dll")]
static extern short VkKeyScan(char ch);
static public Key ResolveKey(char charToResolve)
{
return KeyInterop.KeyFromVirtualKey(VkKeyScan(charToResolve));
}
#2
7
Try using the ConvertFrom method of the System.Windows.Input.KeyConverter class.
尝试使用System.Windows.Input.KeyConverter类的ConvertFrom方法。
#3
1
Hi Just convert that way
嗨,只需转换那种方式
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)
In my case I press "ENTER" on my keyboard, O
is going into ENTER {13}
and ChValue is going into Character Code 13
For TAB
Key I will receive Character Code 9
that way for example.
在我的情况下,我按下键盘上的“ENTER”,O进入ENTER {13},ChValue进入字符代码13对于TABKey,我将以这种方式接收字符代码9。
#4
1
Recently I found a great answer for similar question from Jon Hanna which can handle control key states as well:
最近我找到了Jon Hanna的类似问题的一个很好的答案,它可以处理控制关键状态:
This one might be more easily explained with an example program than anything else:
使用示例程序比使用其他任何内容更容易解释这个:
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
}
}
}
Output:
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
(Though your own console might mess up ש and/or é depending on settings and fonts).
(虽然你自己的控制台可能会根据设置和字体搞乱和/或é)。
Read full descriptions from referenced answer
阅读参考答案的完整描述
#1
23
[DllImport("user32.dll")]
static extern short VkKeyScan(char ch);
static public Key ResolveKey(char charToResolve)
{
return KeyInterop.KeyFromVirtualKey(VkKeyScan(charToResolve));
}
#2
7
Try using the ConvertFrom method of the System.Windows.Input.KeyConverter class.
尝试使用System.Windows.Input.KeyConverter类的ConvertFrom方法。
#3
1
Hi Just convert that way
嗨,只需转换那种方式
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)
In my case I press "ENTER" on my keyboard, O
is going into ENTER {13}
and ChValue is going into Character Code 13
For TAB
Key I will receive Character Code 9
that way for example.
在我的情况下,我按下键盘上的“ENTER”,O进入ENTER {13},ChValue进入字符代码13对于TABKey,我将以这种方式接收字符代码9。
#4
1
Recently I found a great answer for similar question from Jon Hanna which can handle control key states as well:
最近我找到了Jon Hanna的类似问题的一个很好的答案,它可以处理控制关键状态:
This one might be more easily explained with an example program than anything else:
使用示例程序比使用其他任何内容更容易解释这个:
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
}
}
}
Output:
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
(Though your own console might mess up ש and/or é depending on settings and fonts).
(虽然你自己的控制台可能会根据设置和字体搞乱和/或é)。
Read full descriptions from referenced answer
阅读参考答案的完整描述