【问题标题】:How to get a combination of keys in c#如何在c#中获取组合键
【发布时间】:2011-03-15 17:12:09
【问题描述】:

如何在 C# 表单上捕获 Ctrl + Alt + K + P 键? 谢谢

【问题讨论】:

  • 全局或仅当表单具有焦点时?

标签: c# keyboard keyboard-shortcuts keyboard-events


【解决方案1】:

查看这篇关于在 c# 中设置热键的精彩博文

这里还有一篇很好的文章解释了所有这些

【讨论】:

    【解决方案2】:

    MessageFilters 可以在这种情况下为您提供帮助。

        public class KeystrokMessageFilter : System.Windows.Forms.IMessageFilter
        {
            public KeystrokMessageFilter() { }
    
            #region Implementation of IMessageFilter
    
            public bool PreFilterMessage(ref Message m)
            {
                if ((m.Msg == 256 /*0x0100*/))
                {
                    switch (((int)m.WParam) | ((int)Control.ModifierKeys))
                    {
                        case (int)(Keys.Control | Keys.Alt | Keys.K):
                            MessageBox.Show("You pressed ctrl + alt + k");
                            break;
                        //This does not work. It seems you can only check single character along with CTRL and ALT.
                        //case (int)(Keys.Control | Keys.Alt | Keys.K | Keys.P):
                        //    MessageBox.Show("You pressed ctrl + alt + k + p");
                        //    break;
                        case (int)(Keys.Control | Keys.C): MessageBox.Show("You pressed ctrl+c");
                            break;
                        case (int)(Keys.Control | Keys.V): MessageBox.Show("You pressed ctrl+v");
                            break;
                        case (int)Keys.Up: MessageBox.Show("You pressed up");
                            break;
                    }
                }
                return false;
            }
    
            #endregion
    
    
        }
    

    现在在您的 C# WindowsForm 中,注册 MessageFilter 以捕获击键和组合。

    public partial class Form1 : Form
    {
        KeystrokMessageFilter keyStrokeMessageFilter = new KeystrokMessageFilter();
    
        public Form1()
        {
            InitializeComponent();
        }       
        private void Form1_Load(object sender, EventArgs e)
        {
            Application.AddMessageFilter(keyStrokeMessageFilter);
        }
    }
    

    不知何故,它只检测到 Ctrl + Alt + K。请阅读 MessageFilter 代码中的注释。

    【讨论】:

      【解决方案3】:

      我不确定你是否可以。但是,您可以做的是 Visual Studio 的做法。 它有 Ctrl + KC 等快捷键。您首先按 Ctrl+K,然后按住 Ctrl 并按 C。在您的情况下,您可以检查 Ctrl+Alt+K,P

      您可以首先检查 Ctrl+Alt+K 就像在其他答案中所做的那样,然后将成员变量/标志设置为表示已按下 Ctrl+Alt+K。在检查 K 的相同方法中,您可以检查 P,如果您刚刚设置的标志设置为 true,则执行您需要执行的任何操作。否则将标志设置回 false。

      粗略的伪代码:

      private bool m_bCtrlAltKPressed = false;
      
      public void KeyDown() {
        if (Ctrl+Alt+K)
        {
          m_bCtrlAltKPressed = true;
        }
        else if (Ctrl+Alt+P && m_bCtrlAltKPressed) {
          //do stuff
        }
        else {
          m_bCtrlAltKPressed = false;
        }
      }
      

      希望这已经足够清楚了。

      【讨论】:

        【解决方案4】:

        这是一个和弦,如果不记住和弦的第一个键击,您就无法检测到它。这有效:

        public partial class Form1 : Form {
            public Form1() {
                InitializeComponent();
            }
            private bool prefixSeen;
        
            protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
                if (prefixSeen) {
                    if (keyData == (Keys.Alt | Keys.Control | Keys.P)) {
                        MessageBox.Show("Got it!");
                    }
                    prefixSeen = false;
                    return true;
                }
                if (keyData == (Keys.Alt | Keys.Control | Keys.K)) {
                    prefixSeen = true;
                    return true;
                }
                return base.ProcessCmdKey(ref msg, keyData);
            }
        }
        

        【讨论】:

        • 这不会也捕获重复键吗?例如,如果使用 CTRL + P + P 之类的和弦?
        • 重复键会产生 Ctrl+P Ctrl+P。所以没有。
        • 我刚刚编译并测试了代码,如果和弦使用相同的键两次,它确实(错误地)捕获重复的键。例如,按住 CTRL + ALT + P 将触发 CTRL + ALT + P + P 和弦。
        • 那你做错了,把第二个 if() 语句中的 Keys.Alt 和 Keys.Control 去掉。
        • 不,那也行不通。但这不是重点。此代码不适用于某些和弦,我想向其他用户指出这一点。
        【解决方案5】:

        当组合中的一个键被按下时,您可以使用GetKeyState 来获取其他键的状态。这是表单上的示例。

        using System.Linq;
        using System.Runtime.InteropServices;
        using System.Windows.Forms;
        
        namespace DetectKeyChord
        {
            public partial class Form1 : Form
            {
                private const int WM_KEYDOWN = 0x100;
                private const int KEY_PRESSED = 0x80;
        
                public Form1()
                {
                    InitializeComponent();
                }
        
                public void ShortcutAction()
                {
                    MessageBox.Show("Ctrl+Alt+K+P has been pressed.");
                }
        
                private bool IsKeyDown(Keys key)
                {
                    return (NativeMethods.GetKeyState(key) & KEY_PRESSED) == KEY_PRESSED;
                }
        
                protected override void WndProc(ref Message m)
                {
                    if (m.Msg == WM_KEYDOWN)
                    {
                        //If any of the keys in the chord have been pressed, check to see if
                        //the entire chord is down.
                        if (new[] { Keys.P, Keys.K, Keys.ControlKey, Keys.Menu }.Contains((Keys)m.WParam))
                        {
                            if (IsKeyDown(Keys.ControlKey) && IsKeyDown(Keys.Menu) && IsKeyDown(Keys.K) && IsKeyDown(Keys.P))
                            {
                                this.ShortcutAction();
                            }
                        }
                    }
                    base.WndProc(ref m);
                }
            }
        
            public static class NativeMethods
            {
                [DllImport("USER32.dll")]
                public static extern short GetKeyState(Keys nVirtKey);
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-12-27
          • 2018-10-22
          • 1970-01-01
          • 1970-01-01
          • 2020-01-26
          • 2013-03-17
          相关资源
          最近更新 更多