【问题标题】:How can I grab a double key stroke in .NET如何在 .NET 中获取双键击
【发布时间】:2008-12-30 04:29:51
【问题描述】:

如何使用 C# 在 .NET 中获取 ^MM (CTRL + M + M) 之类的内容?

【问题讨论】:

  • 请提供一些上下文。大概你说的是 WinForms?
  • 这在技术上称为“和弦”
  • 谢谢...我不知道名字:)

标签: c# .net key


【解决方案1】:

这是一种方法:

bool mSeenCtrlM;

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
  if (keyData == (Keys.Control | Keys.M)) {
    mSeenCtrlM = !mSeenCtrlM;
    if (!mSeenCtrlM) {
      MessageBox.Show("yada");
    }
    return true;
  }
  mSeenCtrlM = false;
  return base.ProcessCmdKey(ref msg, keyData);
}

【讨论】:

    【解决方案2】:

    这只是一个猜测,您可以在每次击键时存储键和键修饰符,然后下次通过检查最后按下的键是否匹配序列。

    您可以在 ProcessCmdKey 或 OnKeyPress 中实现这一点。

    【讨论】:

    • 在此之上,您可能希望记下第一次按键期间的时间,然后计算时间差以区分按键顺序而不是普通按键。
    • 视情况而定,你可以做 Visual Studio 所做的,并在状态栏中显示一条小消息,说请按和弦的第二部分,然后使用 ESC 取消和弦
    【解决方案3】:

    正如另一张海报所链接的,ModiferKeys 是确定是否按下 Shift 或 Control 的方法。或者,如果您覆盖 ProcessCmdKeys 这是一种方法:

        private static bool lastKeyWasControlM = false;
    
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == (Keys.Control | Keys.M))
            {
                lastKeyWasControlM = true;
    
                // might want to return true here if Ctrl-M maps to nothing else...
                // Ideally should start a timer and if the 'M' key press happens
                // within a short duration (say 1 second) its a combined key event
                // else its the start of another key event...
            }
            else
            {
                if ((keyData & Keys.M) == Keys.M &&
                     (keyData & Keys.Control) != Keys.Control)
                {
                    // M pressed with no modifier
                    if (lastKeyWasControlM == true)
                    {
                        // Handle Ctrl-M + M combined key press...
    
                        return true;
                    }
                }
    
                lastKeyWasControlM = false;
            }
    
            return base.ProcessCmdKey(ref msg, keyData);
        }
    

    【讨论】:

      【解决方案4】:

      我会建议一个更通用的解决方案。执行以下操作:

      List<Keys> currentKeyStack = new List<Keys>();
      DateTime lastUpdate = DateTime.Now;
      TimeSpan lengthOfTimeForChordStroke = new TimeSpan(0,0,5);  //Whatever you want here.
      protected override bool ProcessCmdKey(Message msg, Keys keyData)
      {
           if (DateTime.Now - LastUpdate > lengthOfTimeForChordStroke)
           {
                currentKeyStack.Clear();
           }
       currentKeyStack.Add(keyData);
      
      //You now have a list of the the last group of keystrokes that you can process for each key command, for example:
      
           if (currentKeyStack.Count == 2) && (currentKeyStack[0] == (Keys.Control | Keys.M)) && (currentKeyStack[1] == (Keys.M))
           {
                MessageBox.Show("W00T!");
           }
      }
      

      代码可能在语法上不正确,但这是一个实现细节。这种事情将更易于扩展以处理所有您的键和弦组合,而不仅仅是一个。

      【讨论】:

        【解决方案5】:

        是的,我意识到这有点晚了,但是这个帖子帮助了我,所以我想我会把它传回去。

        我已经稍微扩展了 GWLlosa 代码...我还尝试慷慨地发表评论。 这使您可以在代码中构建您的键序列。对于 Narven,顺序是。

            private static List<List<Keys>> command = new List<List<Keys>>{
                new List<Keys>{Keys.Control | Keys.M},
                new List<Keys>{Keys.M}
            };
        

                private static List<List<Keys>> command = new List<List<Keys>>{
                new List<Keys>{Keys.Control | Keys.M},
                new List<Keys>{Keys.Control | Keys.M}
            };
        

        取决于他想要做什么。

        完整代码如下。

            // This defines the command sequence. In this case, "ctrl-m, ctrl-m, 1 or 2 or 3 or 4, A"
            private static List<List<Keys>> command = new List<List<Keys>>{
                new List<Keys>{Keys.Control | Keys.M},
                new List<Keys>{Keys.Control | Keys.M},
                new List<Keys>{Keys.D1, Keys.D2, Keys.D3, Keys.D4 },
                new List<Keys>{Keys.A}
            };
        
            private static List<Keys> currentKeyStack = new List<Keys>();
            private static DateTime lastUpdate = DateTime.Now;
        
            // See if key pressed within 750ms (0.75 sec)
            private static TimeSpan lengthOfTimeForChordStroke = new TimeSpan(0, 0, 0, 0, 750);
        
            protected static void ProcessCmdKey(Keys keyData)
            {
                // Merge Modifiers (Ctrl, Alt, etc.) and key (A, B, 1, 2, etc.)
                Keys keySequence = (Control.ModifierKeys | keyData);
        
                if ((TimeSpan)(DateTime.Now - lastUpdate) > lengthOfTimeForChordStroke)
                {
                    Console.WriteLine("Clear");
                    currentKeyStack.Clear();
                }
        
                int index = currentKeyStack.Count();
                Console.WriteLine("Index: " + index);
        
                Console.Write("Command: ");
                foreach (List<Keys> key in command)
                {
                    foreach (Keys k in key)
                    {
                        Console.Write(" | " + k.ToString() + " (" + (int)k + ")");
                    }
                }
                Console.WriteLine();
        
                Console.Write("Stack: ");
                foreach (Keys key in currentKeyStack)
                {
                    Console.Write(" | " + key.ToString() + " (" + (int)key + ")");
                }
                Console.WriteLine();
        
                Console.WriteLine("Diff: " + (TimeSpan)(DateTime.Now - lastUpdate) + " length: " + lengthOfTimeForChordStroke);
                Console.WriteLine("#: " + index + "KeySeq: " + keySequence + " Int: " + (int)keySequence + " Key: " + keyData + " KeyInt: " + (int)keyData);
        
                // .Contains allows variable input, e.g Ctrl-M, Ctrl-M, 1 or 2 or 3 or 4
                if (command[index].Contains(keySequence))
                {
                    Console.WriteLine("Added to Stack!");
                    currentKeyStack.Add(keySequence);
                }
                else
                {
                    // Clear stack since input didn't match
                    Console.WriteLine("Clear");
                    currentKeyStack.Clear();
                }
        
                // When command sequence has been met
                if (currentKeyStack.Count == command.Count())
                {
                    // Do your thing here...
                    Console.WriteLine("CAPTURED: " + currentKeyStack[2]);
                }
        
                // Reset LastUpdate
                Console.WriteLine("Reset LastUpdate");
                lastUpdate = DateTime.Now;
        
                Console.WriteLine("\n");
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-11-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-22
          • 1970-01-01
          相关资源
          最近更新 更多