ProcessCmdKey - wait for KeyUp?

I had the following problem in a WinForms application. I am trying to implement hotkeys, and I need to process key messages whenever the control is active, regardless of whether it is concentrated in a text field inside this control, etc.

Overriding ProcessCmdKey works great for this and does exactly what I want with one exception:

If the user presses and holds the key, ProcessCmdKey continues to raise WM_KEYDOWN events.

However, I want to ensure that the user has to release the button again before another hotkey action is triggered (therefore, if someone sits on the keyboard, this will not cause continuous hotkey events).
However, I cannot find where to catch WM_KEYUP events, so can I set the flag if it should process ProcessCmdKey messages again?

Can anyone help here?

Thanks,

Tom

+5
source share
2 answers

I thought it would be easy, just look at the number of keystrokes. Does not work if modifiers are used. You will also need to see that the key goes up, which requires the implementation of IMessageFilter. This worked:

public partial class Form1 : Form, IMessageFilter {
    public Form1()  {
        InitializeComponent();
        Application.AddMessageFilter(this);
        this.FormClosed += (s, e) => Application.RemoveMessageFilter(this);
    }
    bool mRepeating;
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
        if (keyData == (Keys.Control | Keys.F) && !mRepeating) {
            mRepeating = true;
            Console.WriteLine("What the Ctrl+F?");
            return true;
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }
    public bool PreFilterMessage(ref Message m) {
        if (m.Msg == 0x101) mRepeating = false;
        return false;
    }
}
+9
const int WM_KEYDOWN = 0x100;
const int WM_KEYUP = 0x101;

protected override bool ProcessKeyPreview(ref Message m)
{
    if (m.Msg == WM_KEYDOWN && (Keys)m.WParam == Keys.NumPad6)
    {
        //Do something
    }
    else if (m.Msg == WM_KEYUP && (Keys)m.WParam == Keys.NumPad6)
    {
        //Do something
    }

    return base.ProcessKeyPreview(ref m);
}
+3

All Articles