views:

36

answers:

2

Issue

Weird problem. We've got two forms: the main application window and a settings form. The main form has its KeyPreview set to true, and a method attached to its KeyUp event. This is so that the settings window can be opened with a key shortcut (ctrl-m):

private void MyShortcuts(object sender, KeyEventArgs e)
{
    if (e.Control && e.KeyCode == Keys.M)
    {
        e.Handled = true;
        e.SuppressKeyPress = true;
        MySettings sett = new MySettings();
        sett.Show();
    }
}

Now, that bit works just fine. However, the problem is that despite setting the Handled and SuppressKeyPress properties to true, the KeyUp event is still passed on to the MySettings form. I've traced this to ControlNativeWindow.OnMessage receiving what seems to be a different event (its Handled and SuppressKeyPress properties are set to false), and passing that on to the form and its focused control.

Questions

  • First of all, why is the event passed on despite instructing .Net not to do so?
  • Secondly, how do I prevent the event from firing?

Any ideas will be much appreciated, I run out of them myself.

A: 

Instead of the KeyUp Event you should use the KeyDown event.

If you take a look at the documentation you'll see, that before the KeyUp event a KeyPress event will be thrown and this will be catched by your settings form.

Oliver
That doesn't sound right, and supporting KeyDown comes with problems of its own. You're correct in that the sequence is KeyDown > KeyPress > KeyUp, but if we supported KeyDown, our settings for would receive KeyPress and KeyUp... which is precisely what we wanted to avoid!
Dav
But if you use KeyDown and set e.Handled and e.SupressKeypress to true (like you already did) the events KeyPress and KeyDown wouldn't throw and shouldn't arrive your child form anymore.
Oliver
Really? Wow, didn't realise that - apologies for not trusting your answer fully. Will try that on the next form we implement, sounds good. Thanks for coming back!
Dav
+2  A: 

What's happening here is that the M and the CTRL key are raising two separate KeyUp events (which is normal behavior). When you press CTRL and then M and then lift your finger off of the M key, a KeyUp event is raised, which your handler on the main form catches and uses to show the settings form. You then take your finger off of the CTRL key, which raises another KeyUp event (this time on the settings form, which is now the active form).

On the settings form, you can just check e.Control and ignore the event if it's true.

MusiGenesis
Spot on! Just implemented your solution and it works as expected. Thanks for your time and sharing the knowledge!
Dav