我需要能够读取一个字符,并得到它的语言和键盘布局的关键。从char获取KeyCode?
我知道如何看文化设置和语言。 但是我怎样才能在英语中拿出一个像'S'这样的字母,并且知道它在键盘上的键? 或者对于一个更难的问题,我怎么能把这个字母'ש'知道键盘上的键?
我需要能够读取一个字符,并得到它的语言和键盘布局的关键。从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
(虽然你自己的控制台可能陷入困境ש和/或E视设置和字体)。
请注意,在键盘没有AltGr键的情况下,使用Ctrl + Alt作为替代键的Windows kludge正是如何报告的,它只是在较低级别再次被视为单独的,这是一个让Windows键盘不太灵活(Alt + AltGr在Windows中没有意义)。
编辑:KeyboardPointer
的构造函数采用CultureInfo
具有明显的易用性,但对于特定文化的辅助键盘而言,使用该编号对于该编号非常有用。例如。 en-US大多数情况下使用0x0149,但是对于不同的版式(如Dvorak),扩展的字符支持(所谓的“国际美国”需要编写英语)有不同的高级字(0x00010149,0x00020149,0x00030149等)像“naïve”,“façade”或“简历”等词)等等。
非常好的答案。谢谢。 –
您可以解析KeyCode以确定它是否包含您要搜索的信件。对于非英文输入,我想你必须将这些英文字母映射到键盘上以知道它是哪个键。
除非您知道键盘,否则您无法从KeyCode中推导出一个字母,这正是问题所在。 –
@李亚姆,如果有请求,所以应该有一个原因... – serhio
但是,@serhio,如果我们知道推理有一个更合理的解决方案。 – Liam
有很多符号不对应于单个密钥,而是多个密钥。通过使用Dagger(†)符号可以使用组合Alt 0134 \t \t(请参阅http://www.forlang.wsu.edu/help/keyboards.asp)获得,所以这个问题似乎没有合理的解决方案。 – serhio