tags:

views:

117

answers:

3

I have a form with a single text box on it. No other controls. Whenever I type the 'Enter' key or the 'Esc' key, the form functions as I desire; but I hear that horrible Windows error sound. The code looks similar to the following...

public class EntryForm: Form
{
  public EntryForm()
  {
  }

  private void EntryTextBox_KeyUp(object sender, KeyEventArgs e)
  {
    if(e.KeyCode == Keys.Enter)
    {
      // do some stuff
      Hide(); // I've also used DialogResult = DialogResult.OK here
      e.Handled = true;
    }
    else if(e.KeyCode == Keys.Escape)
    {
      Hide(); // I've also used DialogResult = DialogResult.Cancel here
      e.Handled = true;
    }
  }
}

I can 'hack' it and make the noise stop by adding the following code to the form's constructor.

AcceptButton = new Button();
CancelButton = new Button();

As I stated this causes the sound to not play, but I think this is bad form; especially since I don't need a button on the form.

Anyone know why this is the behavior and if there is a cleaner way to stop the error sound from playing?

+1  A: 

In the KeyDown event, set e.Handled = true and e.SuppressKeyPress = true.

Andrew
@Andrew - doing this had no effect whatsoever on the behavior. Thanks for the answer, though, as I had never seen the SuppressKeyPress property before.
John Kraft
+2  A: 

There's a more "correct" fix, one that works regardless of how many controls you have and follows the Windows Forms design model. Paste this code into your form:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
  if (keyData == Keys.Escape || keyData == Keys.Enter) {
    this.Hide();
    return true;
  }
  return base.ProcessCmdKey(ref msg, keyData);
}
Hans Passant
@nobugz - This worked like a champ. Thanks.
John Kraft
+1  A: 

This is too long a reply to Nobugz answer to fit in a comment. If you use Nobugz code as is :

  1. the Form is going to be hidden no matter which control on the form is active and has keyboard input focus, and that is independent of whether the Form has the 'KeyPreview property set to 'true or 'false.

Here's what you need to do to make only a specific control (in this case a TextBox named 'textBox1) be hidden in the ProcessCmdKeys over-ride :

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (msg.HWnd == textBox1.Handle)
    {   
        if  (keyData == Keys.Escape || keyData == Keys.Enter)
        {
            textBox1.Hide();
            return true;
        }
    }
    return base.ProcessCmdKey(ref msg, keyData);
}

Of course if you wanted to handle the case of multiple controls needing to be hidden, you could implement a 'switch statement or whatever to test the msg.HWnd against : note I make the assumption here that all controls that could have keyboard input will have a valid HWnd.

Some memory (vague) of a situation in which I used this technique, and a text input control somehow still had keyboard input focus ... when I did not intend for it to ... makes me want to add an additional test like this :

&& this.ActiveControl == textBox1

But, take that with a "grain of salt" since I can't be certain it is necessary.

BillW
@BillW - Thanks for the extra info. In this case, I do want the entire form to be hidden; but the information is good to know for the future.
John Kraft