【问题标题】:Detect if Pressed Key Combination is Modifier and no Modifier检测按下的键组合是否是修饰符而不是修饰符
【发布时间】:2017-05-25 15:41:26
【问题描述】:

我已经搜索了如何在 c# 中检测键盘组合。

到目前为止,我将表单的KeyDown 事件与KeyPreview = true 一起使用。

我需要检查e.Modifiers 是否是任何修饰符,而e.KeyCode 是否不是修饰符。

最好是一个真正开放的声明,例如:

if(Keys.Modifiers.Contains(e.Modifiers) && !Keys.Modifiers.Contains(e.KeyCode)){}

很遗憾,这不起作用。

这也不起作用,它适用于所有修饰键。

if ((e.Modifiers == Keys.Alt || e.Modifiers == Keys.Control || e.Modifiers == Keys.Shift)
    && (e.KeyCode != Keys.Alt && e.KeyCode != Keys.Control && e.KeyCode != Keys.Shift))

这几乎可以正常工作,但由于没有 Keys.AltKey,所以当点击 ALT 时它会变为 true。

if ((e.Modifiers == Keys.Alt || e.Modifiers == Keys.Control || e.Modifiers == Keys.Shift)
    && (e.KeyCode != Keys.Alt && e.KeyCode != Keys.ControlKey && e.KeyCode != Keys.ShiftKey))

我怎么能做到这一点? e.KeyCode 应该有可能不是修饰符。

原因: 我需要让用户可以使用至少一个修饰符和至少一个其他键来按下任何组合键。

正确获取语句后,如何将组合保存在变量中并在再次输入时检查它的最佳方法是什么?我想过将每个输入的键(当一个是修饰符而另一个不是)保存在List<Keys> 中,并在输入组合的一个键不在列表中时通过foreach 其中return false; 进行检查。

一切都应该尽可能动态。

如何扩展它以检查任何组合?喜欢Ctrl + F + Shift + CCtrl + F + H

谢谢!

迈克尔

【问题讨论】:

    标签: c# forms keydown


    【解决方案1】:

    实现这一点的最简洁的方法可能是使用更底层的 API 来获取当前按下的每个键的数组。这将使您的逻辑更容易,但您必须做一些花哨的导入。

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GetKeyboardState(byte [] lpKeyState);
    
    var array = new byte[256];
    GetKeyboardState(array);
    

    一旦你有了数组,你就可以同时扫描所有的键,而无需任何更多的 O/S 调用,这应该会产生更少的开销。

    例如,您可以通过类似的方式查看按下了多少键

    int countKeys = array.Count(a => a & 0x80);
    

    如果你只是想检查左alt键是否被按下,你可以使用

    bool leftAlt = (array[(byte)Key.LeftAlt] & 0x80);
    

    【讨论】:

      【解决方案2】:

      我认为您可能必须按照 John Wu 的建议进行操作,或者至少采取一些低级的方式,因为您必须记住最后按下的键。如果您使用“多个”字符键……而不是修饰键,那么您将必须记住最后一个组合键是什么。例如:Ctrl + F + Shift + C... 您必须先记住 Ctrl + F + Shift 部分,然后才能查找“C”字符。

      每当您使用多个“字符”键时,您都必须记住序列中的第一个键。我不确定使用这么多键来完成某件事是否对用户友好。然而,来自@Vivelin How to get a combination of keys in c# 的一种可能的解决方案似乎可以解决问题。它看起来很乱,只有两种不同的条件。

      使用您的示例假设我们正在寻找组合 Ctrl + F + Shift + C 代码基本上将布尔值设置为 true 当满足组合的第一部分 Ctrl + F + Shift 然后它退出。当按下下一个键且组合为Ctrl + Shift + C 时,您将知道此组合Ctrl + F + Shift + C 已满足。这类似于其他程序,您按住控制键,然后按下一个字符,然后不一定同时按下另一个字符。在下面的代码中,当组合被触发时,我使用了一个禁用的文本框来输出。我希望这有帮助。

      private bool keyCombo1 = false;
      private bool keyCombo2 = false;
      
      private void textBox1_KeyDown(object sender, KeyEventArgs e) {
        if (e.Control) {
          if (e.Shift) {
            if (e.KeyCode == Keys.F) {
              keyCombo1 = true;
            }
            else {
              if (e.KeyCode == Keys.C && keyCombo1) {
                textBox2.AppendText("Key Combo 1 hit" + Environment.NewLine);
              }
              else {
                keyCombo1 = false;
              }
            }
          }
          else {
            // control only no-shift
            if (e.KeyCode == Keys.F) {
              keyCombo2 = true;
            }
            else {
              if (e.KeyCode == Keys.H && keyCombo2) {
                textBox2.AppendText("Key Combo 2 hit" + Environment.NewLine);
              }
              else {
                keyCombo2 = false;
              }
            }
          }
        }
        else {
          // no control key pressed
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-11
        • 2011-08-01
        • 2014-07-30
        • 2015-01-16
        • 1970-01-01
        • 2012-02-05
        • 1970-01-01
        相关资源
        最近更新 更多