3

I am Working with C# and Windows Forms and want to use Ctrl+"Oemplus" as a function key for my application. I use a German keyboard and this key is located 2 keys right of the letter P (that ist then "+"). Whenever I press this key in combination with Ctrl and the focus is on a TextBox I get a beep.
This also happens when I switch to an US keyboard layout (still using my German keyboard). This is then the ] key.
The same happens when pressing this key while in Internet Explorers address bar. My question is:

  1. Why does this key combination produce a beep in a TextBox.
  2. How can I avoid the beep?

Thanks for any efforts you put on this.
Update:
I tried it on an US/Thai keyboard and get the beep as well. This happens no matter what logical keyboard layout I use (German, US, Thai).
The beep also happens in Windows Explorer in the address bar but not in the search box.

DySoS
  • 105
  • 1
  • 6
  • It probably has some built-in functionality that isn't available at that moment, so it beeps. You could try overriding OnPress or OnRelease and check for that combination so you can mark it as handled, so the beep won't occur. – SimpleVar Aug 05 '12 at 21:51
  • Do you have a numpad? What happens when you use the + key from it? Or in case you're using a laptop the "Ctrl+Fn+Plus" combination? – juan.facorro Aug 05 '12 at 21:56
  • @Yorye Nathan: I already have an application wide keyboard hook and mark the key as handled. It still beeps. With OnPress/OnRelease you mean OnKeyDown/OnKeyUP? – DySoS Aug 06 '12 at 07:16
  • @juan.facorro: On the numeric keypad I don't get the beep. As the beep does not depend on the logical value of the key (+ or ]) but its physical position this is expected. – DySoS Aug 06 '12 at 07:18

3 Answers3

7

It is very unclear what you hope to happen when you press that keystroke. TextBox leaves no doubt about it, it BEEPs! because it can see that the user is trying to do something special but it doesn't know exactly what. Good reason to beep you. Solution is to implement magic, in the //.. comment in this next snippet. With the extra code to stop the beep at the end:

    private void textBox1_KeyDown(object sender, KeyEventArgs e) {
        if (e.KeyData == (Keys.Control | Keys.Oemplus)) {
            // Invoke magic
            //...

            // Magic is done now:
            e.Handled = e.SuppressKeyPress = true;
        }
    }
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • I do not expect that something happens automatically. I want to handle the keystroke myself. The problem is that I do not get rid of the beep. I already have an application wide keyboard hook that sets the key to handled. But ist still beeps. There are many Ctrl+"Key" combinations the TextBox does not understand but does not beep either. I would like to understand what this specific combination is supposed to do automatically before I handle it and thus block some built-in function. However, your solution works. Shame on me that I didn't try this before. – DySoS Aug 06 '12 at 07:28
3

What I believe is happening is that the key combination is not allowed for the Textbox, therefore you are getting the error. You can test for the Key Combination by this code( using the right bracket key in EN Windows) it is using SuppressKeyPress to prevent the Key Combination from being passed to the underlying control to prevent the beep.

private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
    if (ModifierKeys == Keys.Control)
        if (e.KeyValue == 221) // You may need to determine this value for your keyboard layout.
        {
            textBox1.Text += " + "; // Handle the Key combination.
            e.SuppressKeyPress = true;  // Prevents key from being passed to underlying control
        }

}
Mark Hall
  • 53,938
  • 9
  • 94
  • 111
  • Thanks for your answer. As mentioned to the answer before your code works. The relevant hint was to use SuppressKeyPress in addition to Handled. – DySoS Aug 06 '12 at 07:58
2

After some time I came back on this. What I found unsatisfying with the previous solution was that every TextBox would need that handling for every 'beeping' key I use for something else. Sure I could subclass the TextBox but still I would have two places to change for every key with this behavior (the handling and the beep suppression).

Actually I use Ctrl+'+' as a command key. I did this with a global keyboard hook because the action should be available on and impact all forms. Instead I handle this now in a base form using the following code:

    // Avoid beep on Ctrl+'+' in TextBox.
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        Keys key = keyData & Keys.KeyCode;
        bool alt = keyData.HasFlag(Keys.Alt);
        bool shift = keyData.HasFlag(Keys.Shift);
        bool control = keyData.HasFlag(Keys.Control);
        if (key == Keys.Oemplus && !shift && control && !alt)
        {
            // Perform the action for Ctrl+'+'
            return true;
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }

For me this seems the "correct" Position and way to handle a command key. The beep is gone without any additional handling and I don't have to worry if additional command keys produce a beep or not.

When the form had a menu or toolbar this would be handled automatically by the shortcut defined for the menu item. But my forms don't have a menu or toolbar.

DySoS
  • 105
  • 1
  • 6
  • Anything *other* than a global keyboard hook would be a valid option. Calling the `RegisterHotKey` function is another possible approach. – Cody Gray - on strike Apr 24 '13 at 23:26
  • @Cody Gray: Thank you for the hint to RegisterHotKey. And also I understood that using a global keyboard hook was the wrong approach. – DySoS Apr 25 '13 at 08:37