|
The C# Column
Handling keyboard & mouse messages
WinForms
process keyboard messages by overriding virtual methods inherited from the Form
class. The following table lists the virtual methods corresponding to the keyboard
events.
| Method |
Called when |
Argument Type |
| OnKeyDown |
A key is pressedKey |
EventArgs
|
| OnKeyPress |
A character is typedKeyPress
|
EventArgs |
| OnKeyUp |
A Key is releasedKey |
EventArgs
|
The OnKeyDown( ) and OnKeyUp( ) methods correspond to the
WM_KEYDOWN and WM_KEYUP message handlers in Windows. The KeyEventArgs class
has a property KeyCode that identifies the key pressed. The OnKeyPress( ) method
is equivalent to the WM_CHAR message handler and is invoked when a character
key is pressed. The KeyPressEventArgs class has a property KeyChar that gives
the outcome after taking into account the state of other keys. For example,
OnKeyDown( ) will tell us whether key ‘A’ is pressed or not, whereas,
OnKeyPress( ) will tell whether ‘A’ is in uppercase or lowercase.
The KeyEventArgs class has a property called Modifiers that
contains the status of the modifier keys such as ‘Ctrl’, ‘Alt’
and ‘Shift’. So, to check whether Ctrl + A is pressed, we can write
the if condition as follows.
if ( ( e.KeyCode
== Keys.A ) && ( e.Modifiers ==
Keys.Control ) )
MessageBox.Show ( “Ctrl + A pressed” ) ;
Keys is an
enum that specifies the key codes and modifiers.
The Handled property can restrict the controls placed on
the form from handling the keyboard events and allow them to be handled only
at the form level. For this, form’s Handled property should be set to
true. Setting the Handled property to true in the OnKeyPress( ) method indicates
that the KeyPress event is already handled. The Handled property is also useful
in a situation when we want that only certain characters should get entered
in the textbox, others should not. For example, if we want that a textbox should
take only alphabets and should ignore digits and special symbols, then the Handled
property should be set to false if alphabets are entered and to true otherwise.
This is to be done in the KeyPress event handler added for the textbox, as shown
below.
private void textBox1_KeyPress ( object sender, KeyPressEventArgs
e )
{
if ( ( e.KeyChar >= 97 && e.KeyChar <= 122 ) ||
( e.KeyChar >= 65 && e.KeyChar <= 91 ) )
e.Handled = false ;
else
e.Handled = true ;
}
Unlike the Handled property, if the form’s KeyPreview
property is set to true, it receives all the three keyboard events plus the
control having focus also receives the events. For example, if the textbox has
the key input focus and the form’s KeyPreview property is on, firstly
the form will receive the events and then the textbox will receive the key that
was pressed. We can use the KeyPreview property to filter the keys before a
control receives it. For example, we want to design a registration form having
many text boxes. If user enters a value and presses the Enter key, the next
textbox should get the focus. For this, instead of adding keyboard events to
each textbox and a check for the Enter key press, we can add the KeyDown event
handler to the form and check whether the Enter key is pressed. The code to
shift the focus is given below.
private void Form1_KeyDown ( object
sender, KeyEventArgs e )
{
if ( e.KeyCode == Keys.Return )
{
Control c = GetNextControl ( ActiveControl, true ) ;
c.Focus( ) ;
}
}
The ActiveControl property returns the reference of the control
that is currently selected. The GetNextControl( ) method returns the control
next to the specified control in tab order. The focus is set on the next control
using the Focus( ) method.
Mouse events raised on mouse-click resemble the Windows mouse
messages. The MouseDown, MouseMove and MouseUp events occur when the mouse is
clicked, moved and released respectively. The type of parameters the event handlers
receive is MouseEventArgs.
We will now demonstrate using mouse messages in a ‘TimeZone’
application. In this WinForm based application we will display a World map on
the form. As the user moves the cursor on the map, names of places appear in
a small pop-up window.
As a first step to creating this application, we display
two lines intersecting each other at the cursor position, as shown in the following
figure. The point of intersection changes as the cursor position changes.
Add x and y as private data members of the Form class. Add
the MouseMove event handler and add the code in it as shown below.
private void Form1_MouseMove ( object sender,
MouseEventArgs e )
{
Graphics g = CreateGraphics( ) ;
int w = ClientSize.Width ;
int h = ClientSize.Height ;
// Erase Line
Pen p = new Pen ( BackColor ) ;
g.DrawLine ( p, x, 0, x, h ) ;
g.DrawLine ( p, 0, y, w, y ) ;
x = e.X ;
y = e.Y ;
// Draw Line
p = new Pen ( Brushes.Red ) ;
g.DrawLine ( p, x, 0, x, h ) ;
g.DrawLine ( p, 0, y, w, y ) ;
}
Here, we have drawn the lines and erased the previous lines.
We will update this handler as we proceed in the next article.
 |
Yashavant Kanetkar, one of the first
Express Computer columnists, is an established software expert, speaker
and author with several best-sellers to his credit, including titles like
“Let Us C” and the “Fundas” series. Contact him at kanetkar@dcubesoft.com |
|