Key Events: ProcessCmdKey

Overriding ProcessCmdKey in your form is explicitly intended to allow you to implement custom short-cut keystroke handling beyond the built-in mnemonic handling in buttons and menu items.

It is only ever called on a key down event, before the control with the focus gets the KeyDown event and regardless of which client control has the focus. So not associated with KeyUp and not with KeyPress. You return true from your override when you recognize the key, after executing the shortcut function. This prevents the key from being processed any further, it won’t generate any KeyDown/Press/Up events.

It is very rare to use the msg argument of the method, the msg.Msg value will only ever be WM_KEYDOWN or WM_SYSKEYDOWN with the latter message produced when the user held down the Alt key. Which you don’t care about since you can always get if from the keyData argument. Like this:

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
        if (keyData == (Keys.Alt | Keys.F)) {
            // Alt+F pressed
            doSomething();
            return true;
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }

The other modifiers you might want to check with the | operator as used here are Keys.Shift and Keys.Control. So (Keys.Shift | Keys.Control | Keys.F1) checks for Ctrl+Shift+F1. You can interpret the msg data when you want to do something unusual like checking for repeating keys. Check the MSDN docs for the WM_KEYDOWN notification. The msg.LParam value contains a bunch of info about the key stroke.

Note that you only get virtual keys in this method. Keys.F is the F key on the English keyboard layout but not necessarily the same letter for the key in the same location on the user’s layout. Favor the function keys to avoid a documentation headache.

Key repetition is a feature of the keyboard controller and is not limited to typing keys. The arrow and function keys will certainly repeat when held down. You want to ignore KeyPress in this scenario. But if you assign a shortcut key for a key that’s also a typing key (like Keys.F) then you want to always also check for a modifier key so you don’t break controls like TextBox.

Last but not least, don’t forget about the built-in support for mnemonics in the button and menu item controls. Writing their Text property like &OK produces a self-documenting shortcut without needing any code. Operated by the user, in this example, by typing Alt+O.

Leave a Comment