Lack of customization Form.KeyPreview = true?

I wonder which property of Form.KeyPreview is really useful? Why does this exist and what do I "risk" by setting it to true? I assume that it should have some kind of negative effect - otherwise it should not exist at all (or at least be true by default)?

EDIT . I know very well what he is doing. I ask why . Why should I set it to true in order to trigger keyboard events? Why keyboard events do not fire for a form. What is not just standard behavior?

The specific reason I'm asking is: I just set KeyPreview = true in the base form of my application, which inherits all other forms. Can I for any unpleasant surprise?

+24
windows winforms
Mar 05 '10 at 12:37
source share
4 answers

Form.KeyPreview is a bit of anachronism inherited from the Visual Basic object model for form design. Back in the days of VB6, you needed KeyPreview to implement short keystrokes. This is no longer required in Windows Forms, the best solution is ProcessCmdKey() :

 protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if (keyData == (Keys.Control | Keys.F)) { DoSomething(); // Implement the Ctrl+F short-cut keystroke return true; // This keystroke was handled, don't pass to the control with the focus } return base.ProcessCmdKey(ref msg, keyData); } 

But support for KeyPreview helped the legion of VB6 programmers switch to .NET back in the early 2000s. Point KeyPreview or ProcessCmdKey() should allow your user interface to respond to keystrokes. Keyboard messages are usually sent to a control that has focus. The Windows Forms message loop allows code to look into this message before the control sees it. This is important for short keys; implementing a KeyDown for each control that can get the focus to detect them is very impractical.

Setting KeyPreview to True is no problem. An event of the KeyDown form will be fired, it will only matter if it has a code that does something with a keystroke. But be careful that it closely monitors the use of VB6, you cannot see which keystrokes are used for navigation. Like the cursor keys and Tab , Escape and Enter for dialogue. Not a problem with ProcessCmdKey() .

+63
Mar 05 '10 at 13:22
source share

From MSDN

If this property is set to true, the form will receive all KeyPress, KeyDown, and KeyUp. After the event handlers for the keypress processing form are completed, the keypress is then assigned control with focus. For example, if the KeyPreview property is set to true and the currently selected TextBox control is selected, after pressing the key, the event handlers are processed to form the TextBox control and the key is pressed. To handle keyboard events only at the form level and not allow controls to receive keyboard events, set the KeyPressEventArgs.Handled Property to your form, the KeyPress event handler is true.

You can use this property to handle most keystrokes in your application and either handle the keystroke, or call the appropriate control to handle the keystroke. For example, when an application uses function keys, you may need to process keystrokes at the form level rather than the code for each control that can receive keystroke events.

Basically, when you set to true, your form can handle key events, as well as your controls.

EG The user presses the K key, the form event handlers (Key Down, Key Up, Key Pressed) are called, and then the event handlers in the currently active control are called.

EDIT : There are no flaws or unpleasant surprises. The only thing I can come up with is a very small decrease in performance, since for each KeyDown, KeyUp, KeyPressed key, you need to check for event handlers in the form. In addition, if you do not add event handlers to the form and do not do something that might cause problems. you are fine. If you do not need to globally handle key events other than controls, I would suggest leaving this as false to prevent additional checks. On a modern PC, this will not make any noticeable difference.

+4
Mar 05 '10 at 13:00
source share

The standard Windows event model is that the keyboard focus window receives all keyboard events. Remember that in Windows everything - this window - “control” - is just a window that is a child of another window. It is up to this window to send messages to his parent if he wants to do this when some keys are pressed.

To standardize navigation between controls in a dialog box, Windows also provides a "dialog manager." In the native code for modal dialogs, this is handled by the modal outline of the message inside the DialogBox function. For modeless dialogs, you should call IsDialogMessage inside your own message loop. Here's how he steals the Tab and cursor keys to move between controls, and Enter to press the default button. This has the opposite effect of not letting controls handle Enter by default, which typically handle multi-line controls. To find out if the controller wants to process the key, the dialog manager code sends focused control a WM_GETDLGCODE message; if the control responds appropriately, the dialog manager returns FALSE , allowing DispatchMessage actually deliver it to the window procedure, otherwise the dialog manager does its own job.

Windows Forms basically just wraps the old native controls, so it should fit the Win32 event model. It implements the same approach to the dialog manager - therefore, by default, it does not allow you to see the Tab, Return, and cursor keys.

The recommended approach, if you want to process one of these keys, is to override the PreviewKeyDown and set the PreviewKeyDownEventArgs IsInputKey to true .

+2
Mar 23 '15 at 16:24
source share

A simple and trivial, albeit practical reason:

In a game like Space Invaders https://www.mooict.com/c-tutorial-create-a-full-space-invaders-game-using-visual-studio/, the user repeatedly strikes the space bar to vaporize the aliens. When the last invader left, a pop-up text box to say "good work." The user is still jerking with his thumb, presses the spacebar (or maybe just free the keyboard buffer?), And the congratulating MessageBox disappears before it can be read. I could not see a workaround due to the way the forms handle button / space clicks.

My user dialog uses a key preview to pre-process keystrokes sent by GameOverDialog to ignore any space presses. The user must close with the mouse or Enter. This is just a FixedDialog with the words “You won” and the [OK] button.

 public partial class GameOverDialog : Form { public GameOverDialog() { InitializeComponent(); this.MaximizeBox = false; this.MinimizeBox = false; } // keyhandler keypreview = true private void SpaceDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Space) { e.Handled = true; return; } } private void SpaceUp(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Space) { e.Handled = true; return; } } private void button1_Click(object sender, EventArgs e) { this.Close(); } } 

Also, an interesting option that I have not tested: if you think about it, this would be a great way to embed cheats, hidden messages, etc. In harmless dialogs [OK] or any form that allows a key preview.

0
May 16 '19 at 16:58
source share



All Articles