c# - 从字符中获取 KeyCode?

标签 c# char key converters

我需要能够读取一个字符并获取与其语言和键盘布局相关的键。

我知道如何看待文化背景和语言。 但是我怎样才能用英文输入像'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 拼凑正是报告的方式,只是在较低级别再次将两者视为分开的,这是其中之一使 Windows 键盘不太灵活的东西(Alt + AltGr 在 Windows 中毫无意义)。

编辑:采用CultureInfoKeyboardPointer 构造函数显然易于使用,但采用数字的构造函数对于给定文化的辅助键盘很有用。例如。 en-US 最常使用 0x0149,但对于 Dvorak 等变体布局,也有具有不同高位字(0x00010149、0x00020149、0x00030149 等)的变体,扩展了对字符的支持(所谓的“International US”需要写英文像“天真”、“外观”或“简历”)等词。

关于c# - 从字符中获取 KeyCode?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20568393/

相关文章:

javascript - typescript 对象 : How do I restrict the keys to specific strings?

c# - 如何允许用户清除可编辑组合框的值?

c# - Redis 中的 MVC4 和 ServiceStack session

java - 如何将字符转换为字符串

c - 将 char 数组的第一个字符分配给另一个变量

c++ - 我_可以_使用什么作为 std::map 键?

c# - 如何访问服务栈请求对象

c# - C#无控制台应用程序

java - Java 中的 byte、char、int - 位表示

c# - 如何使用与 C# 兼容的 python 创建 RSA 加密 key 对,反之亦然?