views:

53

answers:

1

I have to process enter (among other keys) on win form without it producing error sound, but only if the currently active control didn't process it already.

So, when enter is pressed while in a TextBox or DateTimePicker, i want to process it with a form (without error sound), but if it is pressed, for example, in DataGridView i want it to be handled the way DataGridView does by default.

OnKeyUp solves my problem with handling only unhandled keystrokes (e.Handled) and ProcessCmdKey (this) solves sound problem, but neither solves both.

Any suggestions?

A: 

Kudos for the very interesting question. Unfortunately, I can't seem to find a global event handler for all key presses other than overriding ProcessCmdKey on the main form per this article. Only issue with this method is that the arguments passed into the event handler delegate don't define what control is creating the event :(

So, my only thought is that you need to assign your event handler to every single control in the application. I've written some code that should help show you how to do this. I'm not sure what the adverse effects may be of assigning a KeyPress event handler to every control on your page though, but it's the only feasible solution I see.

Code:

private void Form1_Load(object sender, EventArgs e)
{
    AssignHandler(this);
}

protected void HandleKeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar == (char)Keys.Enter && (sender != this.textBoxToIgnore || sender ! this.gridViewToIgnore))
    {
        PlaySound();  // your error sound function
        e.Handled = true;
    }
}

public void AssignHandler(Control c)
{
    c.KeyPress += new KeyPressEventHandler(HandleKeyPress);
    foreach (Control child in c.Controls)
    {
        AssignHandler(child);
    }
}
regex
The Msg parameter to ProcessCmdKey contains the HWND of the target control (window). You can use Control.FromHandle to get the managed Control object.
Tergiver
@regex: I didn't know that handling KeyPress prevents error sound. I tried it with KeyUp and somehow assumed it wouldn't work with KeyPress either. However, to catch Key events from the Form you don't need to do all this, just set KeyPreview property of the form to true and handle her Key events.
Damir
Damir
@Damir, It looks like Tergiver (see comments on my post) may be more on target than I was. It looks as though the msg parameter provided to the ProcessCmdKey handler contains a windows handle for the window (.NET control) that sent the message. you should be able to use this method rather than assigning a handler to every single control.
regex
Yes, but ProcessCmdKey traps keystroke on the form level and it nevers gets to the controls that could have handled it.
Damir