难以处理瑞士键盘' +'

时间:2014-03-25 18:20:48

标签: c# winforms localization keyboard

我正在做一个工作项目,我有点难过。我们有一个图形显示屏,当按下小键盘上的+或等号键上方的+时,它会处理键盘输入并放大显示。它适用于大多数计算机,但在瑞士(德国)布局上,+键是Shift+1。我们目前正在使用OnKeyDown,它返回按下的键值(如果我试图处理瑞士+,则键值为49)以及指示是否按下shift,control和alt键的布尔变量。我已经看过使用OnKeyPress,但我似乎无法检查是否按下了Control键。

我可能在how to capture the '#' character on different locale keyboards in WPF/C#?有一个潜在的解决方案,但是无论键盘设置的语言是什么,都可以使用外部DLL来正确本地化键盘以使用+键,这看起来非常不优雅。我想相信,自2012年以来,微软已经添加了C#语言的原生内容,以便在外部布局中处理键盘输入,而不会跳过箍。

更糟糕的是,我总能检测到正在使用哪种键盘布局并将其作为一种特殊情况处理,但这似乎是最后的事情。

Keyboard Mapping in .NET处的代码稍微有点用,但它有一些脆弱的位,比如在Keys.Shift而不是{{1}时访问其边界之外的数组它仍然需要拉入外部DLL。这真的是微软认为不重要的东西吗?

编辑:我认为我已经使用上面的代码来处理" .NET中的键盘映射"。我通过按shift和键获取所有键访问的正确值。我有点担心我会错过其他一些涉及添加Control或Alt的案例,但它有效。我仍然更喜欢更优雅的解决方案。

进一步修改Get the char on Control.KeyDown?的技术也适用于给定的控件。

稍后修改 :对。它的功能应该如此,但看起来我的错误总是更简单。非小键盘"加"无论按什么按钮触发KeyCode,都应始终映射到Keys.ShiftKey以获取KeyCode。它不适用于瑞士键盘以及我可能尚未找到的其他键盘。有趣。我不知道我会在哪里举报。

1 个答案:

答案 0 :(得分:0)

最终,我选择了How to convert a virtual-key code to a character according to the current keyboard layout?处的代码。我仍然认为这应该更容易构建到代码中,但它现在应该足够了。

  [DllImport("user32.dll")]
  public static extern int ToUnicode(
      uint wVirtKey,
      uint wScanCode,
      byte[] lpKeyState,
      [Out, MarshalAs(UnmanagedType.LPWStr, SizeParamIndex = 4)] 
        StringBuilder pwszBuff,
      int cchBuff,
      uint wFlags);

  static string GetCharsFromKeys(Keys keys, bool shift, bool altGr)
  {
     var buf = new StringBuilder(256);
     var keyboardState = new byte[256];
     if (shift)
        keyboardState[(int)Keys.ShiftKey] = 0xff;
     if (altGr)
     {
        keyboardState[(int)Keys.ControlKey] = 0xff;
        keyboardState[(int)Keys.Menu] = 0xff;
     }
     ToUnicode((uint)keys, 0, keyboardState, buf, 256, 0);
     return buf.ToString();
  }