Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ProcessCmdKey - wait for KeyUp?

I'm having the following issue in a WinForms app. I'm trying to implement Hotkeys and I need to process Key messages whenever the control is active, no matter if the focus is on a textbox within that control, etc.

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

If a user presses a key and keeps it pressed, ProcessCmdKey keeps triggering WM_KEYDOWN events.

However, what I want to achieve is that the user has to release the button again before another hotkey action would trigger (so, if someone sits on the keyboard it would not cause continuous hotkey events).
However, I can't find where to catch WM_KEYUP events, so I can set a flag if it should process ProcessCmdKey messages again?

Anyone can help out here?

Thanks,

Tom

like image 890
TJF Avatar asked Mar 12 '10 18:03

TJF


2 Answers

I thought it'd be easy, just look at the key's repeat count. Didn't work though if modifiers are used. You'll need to see the key go up as well, that requires implementing 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;
    }
}
like image 145
Hans Passant Avatar answered Sep 28 '22 05:09

Hans Passant


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);
}
like image 41
Paft Avatar answered Sep 28 '22 06:09

Paft