Capturing Key Presses


Capturing key presses is an important Windows programming task. The keys in a computer keyboard are differentiated into several categories. The first category includes the keys that correspond to characters, including alphanumeric and punctuation marks. The second category includes the function keys: F1 to F12. In the last category are control keys: the Control key, the alternate key, the arrow keys, and others. Processing the complete set of keys not only requires you to detect the keying of each individual key but also the combination of several keys.

When the user presses a key in the first category, three events of the control trigger. The three key events occur in the following order:

  1. KeyDown occurs when the user starts pressing the key—in other words, when the key is down.

  2. KeyPress occurs when a key is pressed, after the KeyDown event triggers.

  3. KeyUp occurs when the user releases the key.

The easiest way to capture keyboard input from the user is to use a control's KeyPress event. The event handler for this event receives a System.Windows.Forms.KeyPressEventArgs object containing two properties:

  • Handled is a Boolean indicating whether the key has been handled.

  • KeyChar is a read-only property from which the corresponding character of the pressed key can be obtained.

Because the KeyChar property gives you the character of the key being pressed, displaying the character, for example, is very straightforward. However, some keys do not have visual representation and are not for display. The backspace key, for instance, normally acts as a text-based control to delete the character to the left of the caret and move the caret back by one character. Also, the carriage-return character terminates a line and does not display. For these nonvisual characters, you can simply convert the character into an integer and compare the integer with the ASCII value of the character:

 Dim c As Char = e.KeyChar       ' e is a System.Windows.Forms.KeyPressEventArgs Dim convertedChar As Integer = Convert.ToInt32(c) 

The backspace key will have an integer value of 8, and the carriage-return key will have an integer of 13. However, rather than trying to remember these values, you can conveniently use the System.Windows.Forms.Keys enumeration members. For instance, Keys.Back represents the backspace key, and Keys.Return represents the Enter key. See the .NET Framework class library documentation for a list of values of the Keys enumeration.

For example, Listing 1-3 does different things based on a user's key input. It detects the key pressed by comparing the integer value of the character with a value in the Keys enumeration.

Listing 1-3: Detecting Key Presses

start example
 Dim c As Char = e.KeyChar       ' e is a System.Windows.Forms.KeyPressEventArgs Dim convertedChar As Integer = Convert.ToInt32(c) Select Case convertedChar   Case Keys.Back 'backspace     ' backspace, do something here   Case Keys.Return ' return key     ' Enter was pressed, do something   Case Keys.Escape 'Escape     ' Escape key, do something   Case Else     ' do something End Select 
end example

However, there are problems with using the Control class's KeyPress event alone. For example, the KeyChar property of KeyPressEventArgs has the same value when either the backspace or Ctrl+H is pressed. Therefore, you cannot distinguish the backspace key and Ctrl+H using the KeyPress event alone. Also, function keys, control keys, and arrow keys do not raise the KeyPress event. Function keys generate the KeyDown event, and arrow keys only trigger the KeyUp event. However, KeyUp only triggers when the user releases the key.

Note

It is interesting that pressing arrow keys triggers the Control class's KeyUp event but not its KeyDown event. More interesting is the fact that the Form class's KeyDown event triggers when a user presses an arrow key. The Form class extends ContainerControl, which derives from ScrollableControl. The ScrollableControl class is a direct child class of the Control class. The .NET Framework documentation does not say that the MouseDown event is overridden in ContainerControl, ScrollableControl, or Form. Therefore, the behavior of the KeyDown event should be the same in both the Control class and the Form class. A bug in the implementation of the class library could be the cause of the difference. Or, it could also be because the documentation is not up-to-date. Therefore, in the StyledTextArea control, I avoid using the KeyDown event. Instead, I resort to the ProcessDialogKey method of the Control class.

When you need to capture noncharacter keys (control keys and function keys) when a user is pressing the key, you have to use the ProcessDialogKey method. The ProcessDialogKey method in the Control class is called automatically when a key or a combination of keys on the keyboard is pressed. Unlike the KeyPress event, ProcessDialogKey can capture any key, including the Control key, Tab, and arrow keys. However, it does not give you the character associated with the key; it only tells you which key is being pressed. For example, pressing the A key informs you that the A key has been pressed, but it does not tell you if it is the capital A or small a. There is a way to check the character case, but this requires longer code. For a simpler solution, you can use ProcessDialogKey in conjunction with the KeyPress event. The KeyPress event is invoked after the ProcessDialogKey method is called. Therefore, you can use a flag to tell the KeyPress event handler whether it needs to handle a key press. The ProcessDialogKey method controls the flag. If the key press is a combination of control keys and a character key, the ProcessDialogKey will handle it and reset the flag. On the other hand, if the key pressed is a character key, the ProcessDialogKey will set the flag and let the KeyPress event handler take care of the key press.

When overriding the ProcessDialogKey method, you should return True when the key was handled and False otherwise. Normally, when your ProcessDialogKey method does not process the key, you call the ProcessDialogKey method of the base class and return whatever value was returned by the base class's ProcessDialogKey method.

The ProcessDialogKey method receives one of the Keys enumeration values as its argument. The Keys enumeration allows a bitwise combination of its values.

The argument sent to the ProcessDialogKey method depends on the key(s) being pressed. For instance, if the user pressed the A key, the method will receive Keys.A; if the user pressed Ctrl+S, the value sent is the bitwise combination of the Control key and the S key. The down arrow sends Keys.Down, the up arrow sends Keys.Up, and the right and left arrows send Keys.Right and Keys.Left (respectively). The F1 key sends Keys.F1, and Alt+F4 sends the bitwise combination of Keys.Alt and Keys.F4. When a user presses the Shift key, the method receives Keys.Shift, enabling you to detect whether the user is sending an uppercase or lowercase character.




Real World. NET Applications
Real-World .NET Applications
ISBN: 1590590821
EAN: 2147483647
Year: 2005
Pages: 82

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net