使用当前键盘布局通过键打印字符

时间:2015-12-07 12:32:23

标签: c# .net

在C#中,我正在尝试获取一个字符串,并将其更改为如果用户单击相同的键但是在不同的键盘布局中将收到的字符串。示例:如果用户在en-US布局中单击“a”,他们将获得字符“a”。但如果他们在he-IL布局中这样做,他们就会得到希伯来字符。

我尝试了以下代码:

var kc = new System.Windows.Forms.KeysConverter();
var result = kc.ConvertToString(null, new CultureInfo("he-IL"), Keys.C);
Console.WriteLine(result);

...但我得到了字符串"A"

有没有人知道如何使用.Net功能,没有使用API​​ ToUnicodeEx?

2 个答案:

答案 0 :(得分:1)

没有办法完美地做到这一点,因为部分信息丢失了。

例如,在捷克语键盘布局中,键2给出了ě。如果我不小心使用英文键盘编写,我得到2 - 但这是数字2(在捷克布局中是相同的)还是它应该是ě?在另一个方向,我的特定捷克键盘布局使用Alt-Gr(基本上,Ctrl+Alt)来编写英文键盘字符(例如,{) - 如果我在英语上使用相同的组合键盘,结果是没有。糟糕?

另一个问题是文化不能干净地映射到键盘布局。首先,有三种窗口键盘布局供捷克人选择,每种都有不同的行为,但都属于同一种文化。其次,不同的(物理)键盘可以将不同的虚拟键映射到不同的物理键,这进一步使问题复杂化。

最后,你必须猜测。而且只要你还在猜测,我建议你自己创建一个你可以应用char-by-char的映射表。你可以使用P / Invoke从Keyschar,但你甚至不能开始使用Keys值 - 你所拥有的只是{{1} }。您可以使用简单的函数来处理" common"字符(例如,捷克语和英语通常具有相同的拉丁字符 - chara等等 - 尽管在最常见的布局中,az,反之亦然,所以它仍然很棘手),但这可能不会帮助例如英语与希伯来语。这仍然仍然棘手,但它应该让你足够接近,以便为正确翻译的内容启用手动更正。

就像注释一样,y仅翻译键的名称,它不会进行任何虚拟键盘映射。如果您想将KeysConverter翻译为Keys.Control | Keys.Alt | Keys.Delete(或返回),这会非常有用,但这是有用的。

答案 1 :(得分:0)

我不知道这个解决方案是否合适。也许这是一个非常难看的解决方案,但我真的想与社区分享......你可以向我扔西红柿:)))。

让我们考虑一下我们有语言,例如俄语和英语以及WinForms应用程序。在我看来,我们可以为这些语言创建一些关键映射。我们知道:

  1. e.KeyValue总是等于英文字母,尽管有键盘
  2. 我们知道e.KeyValue总是大写
  3. 所以我们应该创建帮助类。例如:

    public class EnglishRussian
    {
        public int IndexRussian { get; set; }
        public int IndexEnglish { get; set; }
    
        public char EnglishLetter { get; set; }
        public char RussianLetter { get; set; }
    
    }
    

    要定义相反的键值,我们使用字典:

    private void textBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    {
       Dictionary<char, EnglishRussian> letterDictionary = new Dictionary<char, EnglishRussian>();
       letterDictionary.Add('A', new EnglishRussian() {RussianLetter='ф', IndexRussian='ф', EnglishLetter='a', IndexEnglish='a' });
       //You need to add all English letters and their opposite Russian letters
       char ch = (char)e.KeyValue;       
       char yourValue;
       switch(ch)
       {
         case 'A':
            {
              yourValue= letterDictionary[ch].RussianLetter;
              break;
            }            
        }
    }
    

    也许这不是优雅的解决方案,但我的良心是明确的,因为我真的想分享我的想法,至少它适用于一个键盘。