All Control objects support several mouse events, listed in Table 8-2. Three of themMouseEnter, MouseHover, and MouseLeaveare raised, respectively, every time the mouse cursor goes from being outside to inside the control, stays stationary over a control (or at least does not move outside the control; only a single MouseHover event is raised for every MouseEnter/MouseLeave pair, even if the cursor hovers, moves a bit, then hovers again), or leaves the control's airspace. Each event passes an event argument of type EventArgs, which carries no information about the event. No coordinates are passed, for example. These three events tell you only that the mouse cursor has interacted with a control.
Four low level events, also listed in Table 8-2, pass significant information about the event, in a structure of type MouseEventArgs: MouseDown, MouseMove, MouseWheel, and MouseUp. From the properties of the MouseEventArgs argument, listed in Table 8-3, you can tell which button was pressed on the mouse, and the coordinates of the hot spot of the mouse cursor (relative to the top left corner of the control) when the event was raised, in addition to other information.
Finally, there are two high level events: Click and DoubleClick. These events also take an event argument of type EventArgs, meaning that the event has no additional information. (Additional Control properties, listed in Table 8-5, provide information such as the coordinates and the mouse buttons pressed.) A Click event occurs when there is a single press and release of a mouse button while the mouse cursor is over the Control. A DoubleClick event occurs when the mouse button is clicked twice in succession, with the time interval between the clicks less than the number of milliseconds in SystemInformation.DoubleClickTime and the mouse movement between clicks less than the number of pixels in SystemInformation.DoubleClickSize.
Event |
Event argument |
Description |
---|---|---|
Click |
EventArgs |
Raised when the control is clicked. |
DoubleClick |
EventArgs |
Raised when the control is double-clicked. |
MouseEnter |
EventArgs |
Raised when the mouse cursor enters the control. |
MouseHover |
EventArgs |
Raised when the mouse cursor hovers over the control. |
MouseLeave |
EventArgs |
Raised when the mouse cursor leaves the control. |
MouseDown |
MouseEventArgs |
Raised when the mouse cursor is over the control and a mouse button is pressed. |
MouseMove |
MouseEventArgs |
Raised when the mouse cursor is moved over the control. |
MouseWheel |
MouseEventArgs |
Raised when the control has focus and the mouse wheel is rotated. |
MouseUp |
MouseEventArgs |
Raised when the mouse cursor is over the control and a mouse button is released. |
|
Only one mouse button is represented in each event. If you try pressing two mouse buttons simultaneously, you will get two separate Mouse events. (While the Button property of MouseEventArgs is of type MouseButtons, and while theoretically you can use bit-wise combinations to combine two Button enumerated values, you can have only one mouse button per event.) See Table 8-4 for MouseButtons enumeration values.
Property |
Description |
---|---|
Button |
Returns the pressed mouse button. Must be one of the members of the MouseButtons enumeration (listed in Table 8-4). |
Clicks |
Returns the integer number of times the mouse button was pressed and released. Resets after two clicks. |
Delta |
Returns the signed integer number of detents the mouse wheel was rotated. A positive value indicates that the wheel was rotated forward, i.e., away from the user, and a negative value indicates the wheel was rotated backward, i.e., toward the user. |
X |
The X coordinate, in pixels, of the mouse cursor's hot spot when the button was clicked, relative to the top-left corner of the control. |
Y |
The Y coordinate, in pixels, of the mouse cursor's hot spot when the button was clicked, relative to the top-left corner of the control. |
|
Member |
Description |
---|---|
Left |
Left, or primary, mouse button pressed. |
Middle |
Middle mouse button pressed. |
None |
No mouse button pressed. |
Right |
Right, or secondary, mouse button pressed. |
Xbutton1 |
First XButton of five button Microsoft IntelliMouse Explorer pressed. |
Xbutton2 |
Second XButton of five button Microsoft IntelliMouse Explorer pressed. |
The programs listed in Example 8-3 (in C#) and in Example 8-4 (in VB.NET) demonstrate the MouseEnter, MouseHover, and MouseLeave events. These events are handled both for a Button control (which performs no other function in these programs other than acting as a typical control) and for the form. When the mouse cursor enters, hovers over, or leaves either the button or the form, a text string is painted on the form client area with that information. In addition, if the button raises any of these three events, the Text property of the button is changed.
Example 8-3. MouseEnter, MouseHover, and MouseLeave event handling in C# (MouseEnterHoverLeave.cs)
using System; using System.Drawing; using System.Windows.Forms; namespace ProgrammingWinApps { public class MouseEnterHoverLeave : Form { private Button btn; string str = ""; public MouseEnterHoverLeave( ) { Text = "Mouse Enter / Hover / Leave"; Size = new Size(400,400); btn = new Button( ); btn.Parent = this; btn.Location = new Point(50,50); btn.Size = new Size(150,25); btn.MouseEnter += new System.EventHandler(btn_MouseEnter); btn.MouseHover += new System.EventHandler(btn_MouseHover); btn.MouseLeave += new System.EventHandler(btn_MouseLeave); } static void Main( ) { Application.Run(new MouseEnterHoverLeave( )); } private void btn_MouseEnter(object sender, EventArgs e) { btn.Text = "MouseEnter"; str += " Button MouseEnter"; Invalidate( ); } private void btn_MouseHover(object sender, EventArgs e) { btn.Text = "MouseHover"; str += " Button MouseHover"; Invalidate( ); } private void btn_MouseLeave(object sender, EventArgs e) { btn.Text = "MouseLeave"; str += " Button MouseLeave"; Invalidate( ); } protected override void OnMouseEnter(EventArgs e) { base.OnMouseEnter(e); str += " Form MouseEnter"; Invalidate( ); } protected override void OnMouseHover(EventArgs e) { base.OnMouseHover(e); str += " Form MouseHover"; Invalidate( ); } protected override void OnMouseLeave(EventArgs e) { base.OnMouseLeave(e); str += " Form MouseLeave"; Invalidate( ); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics g = e.Graphics; g.DrawString(str, Font, Brushes.Black, 50, 75); } } }
Example 8-4. MouseEnter, MouseHover, and MouseLeave in VB.NET (MouseEnterHoverLeave.vb)
Option Strict On imports System imports System.Drawing imports System.Windows.Forms namespace ProgrammingWinApps public class MouseEnterHoverLeave : inherits Form private btn as Button dim str as string = "" public sub New( ) Text = "Mouse Enter / Hover / Leave" Size = new Size(400,400) btn = new Button( ) btn.Parent = me btn.Location = new Point(50,50) btn.Size = new Size(150,25) AddHandler btn.MouseEnter, AddressOf btn_MouseEnter AddHandler btn.MouseHover, AddressOf btn_MouseHover AddHandler btn.MouseLeave, AddressOf btn_MouseLeave end sub public shared sub Main( ) Application.Run(new MouseEnterHoverLeave( )) end sub private sub btn_MouseEnter(ByVal sender as object, _ ByVal e as EventArgs) btn.Text = "MouseEnter" str = str + vbNewLine + "Button MouseEnter" Invalidate( ) end sub private sub btn_MouseHover(ByVal sender as object, _ ByVal e as EventArgs) btn.Text = "MouseHover" str = str + vbNewLine + "Button MouseHover" Invalidate( ) end sub private sub btn_MouseLeave(ByVal sender as object, _ ByVal e as EventArgs) btn.Text = "MouseLeave" str = str + vbNewLine + "Button MouseLeave" Invalidate( ) end sub protected overrides sub OnMouseEnter(ByVal e as EventArgs) myBase.OnMouseEnter(e) str = str + vbNewLine + "Form MouseEnter" Invalidate( ) end sub protected overrides sub OnMouseHover(ByVal e as EventArgs) myBase.OnMouseHover(e) str = str + vbNewLine + "Form MouseHover" Invalidate( ) end sub protected overrides sub OnMouseLeave(ByVal e as EventArgs) myBase.OnMouseLeave(e) str = str + vbNewLine + "Form MouseLeave" Invalidate( ) end sub protected overrides sub OnPaint(ByVal e as PaintEventArgs) myBase.OnPaint(e) dim g as Graphics = e.Graphics g.DrawString(str, Font, Brushes.Black, 50, 75) end sub end class end namespace
In the constructor of the programs in Example 8-3 and Example 8-4, in addition to setting the Form Text and Size properties, the Button control is instantiated and specified, including the addition of event handlers for the MouseEnter, MouseHover, and MouseLeave events.
btn.MouseEnter += new System.EventHandler(btn_MouseEnter); btn.MouseHover += new System.EventHandler(btn_MouseHover); btn.MouseLeave += new System.EventHandler(btn_MouseLeave);
AddHandler btn.MouseEnter, AddressOf btn_MouseEnter AddHandler btn.MouseHover, AddressOf btn_MouseHover AddHandler btn.MouseLeave, AddressOf btn_MouseLeave
Each event handler changes the Text property of the button and then concatenates a new line character and some appropriate text to the member string variable str. The Invalidate method is called, which causes a Paint event to be raised for the Form. The btn_MouseEnter looks like:
private void btn_MouseEnter(object sender, EventArgs e) { btn.Text = "MouseEnter"; str += " Button MouseEnter"; Invalidate( ); }
private sub btn_MouseEnter(ByVal sender as object, _ ByVal e as EventArgs) btn.Text = "MouseEnter" str = str + vbNewLine + "Button MouseEnter" Invalidate( ) end sub
When the Form's Paint event is raised, the OnPaint method is invoked. This is overridden by a method that first chains up to the base method, ensuring that any other methods registered with the delegate will be invoked. The overridden OnPaint method then instantiates a Graphics object and draws the str text string.This overridden OnPaint method looks like:
protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics g = e.Graphics; g.DrawString(str, Font, Brushes.Black, 50, 75); }
protected overrides sub OnPaint(ByVal e as PaintEventArgs) myBase.OnPaint(e) dim g as Graphics = e.Graphics g.DrawString(str, Font, Brushes.Black, 50, 75) end sub
Notice that there is only a single string being drawn, which is built up of all the event messages. This obviates the need to keep track of the vertical coordinate, as was done in Example 8-1 and Example 8-2.
Compiling and running the program, and then moving the mouse over the button, hovering a bit, and moving the mouse off of the form results in the screenshot shown in Figure 8-1.
The sequence of events is interesting. The cursor first enters the Form, and then leaves the Form as it enters the Button. Next, the cursor hovers over the Button, and then leaves the Button and enters the Form once again. It finally leaves the Form for good, moving onto the desktop.
Figure 8-1. MouseEnterHoverLeave in action
The programs in Example 8-5 (in C#) and Example 8-6 (in VB.NET) demonstrate all mouse events, including MouseEnter, MouseHover, MouseLeave, MouseDown, MouseMove, MouseUp, MouseWheel, Click, and DoubleClick.
|
The code that differs from the previous example is highlighted.
Example 8-5. Mouse events in C# (MouseEvents.cs)
using System; using System.Drawing; using System.Windows.Forms; namespace ProgrammingWinApps { public class MouseEvents : Form { private Label lbl; private Button btnReset; private TextBox txt; public MouseEvents( ) { Text = "Mouse Events"; Size = new Size(400,600); btnReset = new Button( ); btnReset.Parent = this; btnReset.Location = new Point(250,50); btnReset.Text = "Reset"; btnReset.Click += new System.EventHandler(btnReset_Click); lbl = new Label( ); lbl.Parent = this; lbl.Location = new Point(50,50); lbl.Size = new Size(150,25); lbl.BorderStyle = BorderStyle.Fixed3D; lbl.MouseEnter += new System.EventHandler(lbl_MouseEnter); lbl.MouseHover += new System.EventHandler(lbl_MouseHover); lbl.MouseLeave += new System.EventHandler(lbl_MouseLeave); lbl.MouseDown += new System.Windows.Forms.MouseEventHandler(lbl_MouseDown); // Comment out to reduce quantity of text generated. // lbl.MouseMove += new // System.Windows.Forms.MouseEventHandler(lbl_MouseMove); lbl.MouseUp += new System.Windows.Forms.MouseEventHandler(lbl_MouseUp); lbl.MouseWheel += new System.Windows.Forms.MouseEventHandler(lbl_MouseWheel); lbl.Click += new System.EventHandler(lbl_Click); lbl.DoubleClick += new System.EventHandler(lbl_DoubleClick); txt = new TextBox( ); txt.Parent = this; txt.Location = new Point(50,90); txt.Size = new Size(300,475); txt.BorderStyle = BorderStyle.FixedSingle; txt.Multiline = true; txt.ScrollBars = ScrollBars.Vertical; } static void Main( ) { Application.Run(new MouseEvents( )); } private void btnReset_Click(object sender, EventArgs e) { lbl.Text = ""; txt.Text = ""; } private void lbl_MouseEnter(object sender, EventArgs e) { lbl.Text = "MouseEnter"; TextBoxDraw("Label MouseEnter"); } private void lbl_MouseHover(object sender, EventArgs e) { lbl.Text = "MouseHover"; TextBoxDraw("Label MouseHover"); } private void lbl_MouseLeave(object sender, EventArgs e) { lbl.Text = "MouseLeave"; TextBoxDraw("Label MouseLeave"); } private void lbl_MouseDown(object sender, MouseEventArgs e) { lbl.Text = "MouseDown"; string str; str = "Label MouseDown"; str += " Button: " + e.Button.ToString( ); str += " Clicks: " + e.Clicks.ToString( ); str += " Delta: " + e.Delta.ToString( ); str += " X: " + e.X.ToString( ); str += " Y: " + e.Y.ToString( ); TextBoxDraw(str); } private void lbl_MouseMove(object sender, MouseEventArgs e) { lbl.Text = "MouseMove"; string str; str = "Label MouseMove"; str += " Button: " + e.Button.ToString( ); str += " Clicks: " + e.Clicks.ToString( ); str += " Delta: " + e.Delta.ToString( ); str += " X: " + e.X.ToString( ); str += " Y: " + e.Y.ToString( ); TextBoxDraw(str); } private void lbl_MouseUp(object sender, MouseEventArgs e) { lbl.Text = "MouseUp"; string str; str = "Label MouseUp"; str += " Button: " + e.Button.ToString( ); str += " Clicks: " + e.Clicks.ToString( ); str += " Delta: " + e.Delta.ToString( ); str += " X: " + e.X.ToString( ); str += " Y: " + e.Y.ToString( ); TextBoxDraw(str); } private void lbl_MouseWheel(object sender, MouseEventArgs e) { lbl.Text = "MouseWheel"; string str; str = "Label MouseWheel"; str += " Button: " + e.Button.ToString( ); str += " Clicks: " + e.Clicks.ToString( ); str += " Delta: " + e.Delta.ToString( ); str += " X: " + e.X.ToString( ); str += " Y: " + e.Y.ToString( ); TextBoxDraw(str); } private void lbl_Click(object sender, EventArgs e) { lbl.Text = "Click"; TextBoxDraw("Label Click"); } private void lbl_DoubleClick(object sender, EventArgs e) { lbl.Text = "DoubleClick"; TextBoxDraw("Label DoubleClick"); } protected override void OnMouseEnter(EventArgs e) { base.OnMouseEnter(e); TextBoxDraw("Form MouseEnter"); } protected override void OnMouseHover(EventArgs e) { base.OnMouseHover(e); TextBoxDraw("Form MouseHover"); } protected override void OnMouseLeave(EventArgs e) { base.OnMouseLeave(e); TextBoxDraw("Form MouseLeave"); } private void TextBoxDraw(String str) { txt.AppendText(" " + str); } } }
Example 8-6. Mouse events in VB.NET (MouseEvents.vb)
Option Strict On imports System imports System.Drawing imports System.Windows.Forms namespace ProgrammingWinApps public class MouseEvents : inherits Form private lbl as Label private txt as TextBox private WithEvents btnReset as Button public sub New( ) Text = "Mouse Events" Size = new Size(400,600) btnReset = new Button( ) btnReset.Parent = me btnReset.Location = new Point(250,50) btnReset.Text = "Reset" lbl = new Label( ) lbl.Parent = me lbl.Location = new Point(50,50) lbl.Size = new Size(150,25) lbl.BorderStyle = BorderStyle.Fixed3D AddHandler lbl.MouseEnter, AddressOf lbl_MouseEnter AddHandler lbl.MouseHover, AddressOf lbl_MouseHover AddHandler lbl.MouseLeave, AddressOf lbl_MouseLeave AddHandler lbl.MouseDown, AddressOf lbl_MouseDown ' Comment out to reduce quantity of text generated. ' AddHandler lbl.MouseMove, AddressOf lbl_MouseMove AddHandler lbl.MouseUp, AddressOf lbl_MouseUp AddHandler lbl.MouseWheel, AddressOf lbl_MouseWheel AddHandler lbl.Click, AddressOf lbl_Click AddHandler lbl.DoubleClick, AddressOf lbl_DoubleClick txt = new TextBox( ) txt.Parent = me txt.Location = new Point(50,90) txt.Size = new Size(300,475) txt.BorderStyle = BorderStyle.FixedSingle txt.Multiline = true txt.ScrollBars = ScrollBars.Vertical end sub public shared sub Main( ) Application.Run(new MouseEvents( )) end sub private sub btnReset_Click(ByVal sender as object, _ ByVal e as EventArgs) _ Handles btnReset.Click lbl.Text = "" txt.Text = "" end sub private sub lbl_MouseEnter(ByVal sender as object, _ ByVal e as EventArgs) lbl.Text = "MouseEnter" TextBoxDraw("Label MouseEnter") end sub private sub lbl_MouseHover(ByVal sender as object, _ ByVal e as EventArgs) lbl.Text = "MouseHover" TextBoxDraw("Label MouseHover") end sub private sub lbl_MouseLeave(ByVal sender as object, _ ByVal e as EventArgs) lbl.Text = "MouseLeave" TextBoxDraw("Label MouseLeave") end sub private sub lbl_MouseDown(ByVal sender as object, _ ByVal e as MouseEventArgs) lbl.Text = "MouseDown" dim str as string str = "Label MouseDown" str = str + vbNewLine + vbTab + "Button: " + e.Button.ToString( ) str = str + vbNewLine + vbTab + "Clicks: " + e.Clicks.ToString( ) str = str + vbNewLine + vbTab + "Delta: " + e.Delta.ToString( ) str = str + vbNewLine + vbTab + "X: " + e.X.ToString( ) str = str + vbNewLine + vbTab + "Y: " + e.Y.ToString( ) TextBoxDraw(str) end sub private sub lbl_MouseMove(ByVal sender as object, _ ByVal e as MouseEventArgs) lbl.Text = "MouseMove" dim str as string str = "Label MouseMove" str = str + vbNewLine + vbTab + "Button: " + e.Button.ToString( ) str = str + vbNewLine + vbTab + "Clicks: " + e.Clicks.ToString( ) str = str + vbNewLine + vbTab + "Delta: " + e.Delta.ToString( ) str = str + vbNewLine + vbTab + "X: " + e.X.ToString( ) str = str + vbNewLine + vbTab + "Y: " + e.Y.ToString( ) TextBoxDraw(str) end sub private sub lbl_MouseUp(ByVal sender as object, _ ByVal e as MouseEventArgs) lbl.Text = "MouseUp" dim str as string str = "Label MouseUp" str = str + vbNewLine + vbTab + "Button: " + e.Button.ToString( ) str = str + vbNewLine + vbTab + "Clicks: " + e.Clicks.ToString( ) str = str + vbNewLine + vbTab + "Delta: " + e.Delta.ToString( ) str = str + vbNewLine + vbTab + "X: " + e.X.ToString( ) str = str + vbNewLine + vbTab + "Y: " + e.Y.ToString( ) TextBoxDraw(str) end sub private sub lbl_MouseWheel(ByVal sender as object, _ ByVal e as MouseEventArgs) lbl.Text = "MouseWheel" dim str as string str = "Label MouseWheel" str = str + vbNewLine + vbTab + "Button: " + e.Button.ToString( ) str = str + vbNewLine + vbTab + "Clicks: " + e.Clicks.ToString( ) str = str + vbNewLine + vbTab + "Delta: " + e.Delta.ToString( ) str = str + vbNewLine + vbTab + "X: " + e.X.ToString( ) str = str + vbNewLine + vbTab + "Y: " + e.Y.ToString( ) TextBoxDraw(str) end sub private sub lbl_Click(ByVal sender as object, _ ByVal e as EventArgs) lbl.Text = "Click" TextBoxDraw("Label Click") end sub private sub lbl_DoubleClick(ByVal sender as object, _ ByVal e as EventArgs) lbl.Text = "DoubleClick" TextBoxDraw("Label DoubleClick") end sub protected overrides sub OnMouseEnter(ByVal e as EventArgs) TextBoxDraw("Form MouseEnter") end sub protected overrides sub OnMouseHover(ByVal e as EventArgs) TextBoxDraw("Form MouseHover") end sub protected overrides sub OnMouseLeave(ByVal e as EventArgs) TextBoxDraw("Form MouseLeave") end sub private sub TextBoxDraw(str as string) txt.AppendText(vbNewLine + str) end sub end class end namespace
Figure 8-2 illustrates the output from Example 8-5 and Example 8-6. As the mouse interacts with either the Form or the Label control, the log of mouse events, including the MouseEventArgs property values, is displayed in the TextBox. Clicking the Reset button clears the TextBox and the Label.
When the mouse cursor is moved from a position over the Form (but not over any child controls) to a position over any of the child controls, a Form MouseLeave event is raised. If this program were tracking the mouse events for the child control (as it is for the Label control), then you would see a concomitant MouseEnter for the child control that the cursor just passed over. This is an effect of the z-order of the controls, a topic covered in Chapter 7. In short, the control on top receives the mouse events.
Figure 8-2. MouseEvents program
The code in this example is very straightforward. The Reset button adds a method called btnReset_Click to the Click event delegate, which sets the values of the Label and TextBox controls to empty strings.
As with the previous example, the Form MouseEnter, MouseHover, and MouseLeave events are overridden. Similar to before, each overridden method appends a string onto the output TextBox. Now, however, rather than call the Invalidate method, which raises a Paint event for the Form, the method TextBoxDraw is called.
TextBoxDraw is a simple method that takes a string as an argument and appends that string to the Text property of the TextBox using the TextBox AppendText method. It is:
private void TextBoxDraw(string str) { txt.AppendText(" " + str); }
private sub TextBoxDraw(str as string) txt.AppendText(vbNewLine + str) end sub
The C# code requires both a carriage return escape character ( ) and a new line escape character ( ) to force a new line in a TextBox control. (Most other controls require only a .)
To track these events, begin by instantiating the Label control lbl:
lbl = new Label( ); lbl.Parent = this; lbl.Location = new Point(50,50); lbl.Size = new Size(150,25); lbl.BorderStyle = BorderStyle.Fixed3D;
lbl = new Label( ) lbl.Parent = me lbl.Location = new Point(50,50) lbl.Size = new Size(150,25) lbl.BorderStyle = BorderStyle.Fixed3D
Then add event handlers to the relevant delegates for all the different mouse events. In C#, the type of event argument is indicated by the name of the event handler delegate to which the event handler method is added (in this example, System.EventHandler and System.Windows.Forms.MouseEventHandler are the delegates).
lbl.MouseEnter += new System.EventHandler(lbl_MouseEnter); lbl.MouseHover += new System.EventHandler(lbl_MouseHover); lbl.MouseLeave += new System.EventHandler(lbl_MouseLeave); lbl.MouseDown += new System.Windows.Forms.MouseEventHandler(lbl_MouseDown); // Comment out to reduce quantity of text generated. // lbl.MouseMove += new // System.Windows.Forms.MouseEventHandler(lbl_MouseMove); lbl.MouseUp += new System.Windows.Forms.MouseEventHandler(lbl_MouseUp); lbl.MouseWheel += new System.Windows.Forms.MouseEventHandler(lbl_MouseWheel); lbl.Click += new System.EventHandler(lbl_Click); lbl.DoubleClick += new System.EventHandler(lbl_DoubleClick);
In VB.NET, the AddHandler syntax is used:
AddHandler lbl.MouseEnter, AddressOf lbl_MouseEnter AddHandler lbl.MouseHover, AddressOf lbl_MouseHover AddHandler lbl.MouseLeave, AddressOf lbl_MouseLeave AddHandler lbl.MouseDown, AddressOf lbl_MouseDown ' Comment out to reduce quantity of text generated. ' AddHandler lbl.MouseMove, AddressOf lbl_MouseMove AddHandler lbl.MouseUp, AddressOf lbl_MouseUp AddHandler lbl.MouseWheel, AddressOf lbl_MouseWheel AddHandler lbl.Click, AddressOf lbl_Click AddHandler lbl.DoubleClick, AddressOf lbl_DoubleClick
|
In the instantiation and specification of the output TextBox, the BorderStyle is set to the FixedSingle BorderStyle enumeration, the Multiline property is set to true, and a vertical scrollbar is added. Here is the code:
txt.BorderStyle = BorderStyle.FixedSingle txt.Multiline = true txt.ScrollBars = ScrollBars.Vertical
The MouseEnter, MouseHover, and MouseLeave event handlers are essentially the same as in the previous example. The events that take an event argument of type MouseEventArgs (MouseDown, MouseMove, MouseUp, and MouseWheel) each output text that displays the values of the event argument properties. The tab character escape sequence ( ) enhances the output.
private void lbl_MouseDown(object sender, MouseEventArgs e) { lbl.Text = "MouseDown"; string str; str = "Label MouseDown"; str += " Button: " + e.Button.ToString( ); str += " Clicks: " + e.Clicks.ToString( ); str += " Delta: " + e.Delta.ToString( ); str += " X: " + e.X.ToString( ); str += " Y: " + e.Y.ToString( ); TextBoxDraw(str); }
The VB.NET event handler uses VB.NET constants to achieve the same effects.
private sub lbl_MouseDown(ByVal sender as object, _ ByVal e as MouseEventArgs) lbl.Text = "MouseDown" dim str as string str = "Label MouseDown" str = str + vbNewLine + vbTab + "Button: " + e.Button.ToString( ) str = str + vbNewLine + vbTab + "Clicks: " + e.Clicks.ToString( ) str = str + vbNewLine + vbTab + "Delta: " + e.Delta.ToString( ) str = str + vbNewLine + vbTab + "X: " + e.X.ToString( ) str = str + vbNewLine + vbTab + "Y: " + e.Y.ToString( ) TextBoxDraw(str) end sub
Experimenting with the program coded in this example and shown in Figure 8-2, you can see that the low-level mouse events occur in the following order for any given control:
The MouseDown and MouseUp events are rolled up into a Click or DoubleClick event. A Click event comes after the MouseDown but before the Mouse Up. A DoubleClick first registers a Click event (with its surrounding MouseDown and MouseUp), followed by a second MouseDown and MouseUp. The events and MouseEventArgs.Click property for a DoubleClick are shown in Figure 8-3. Notice that the Clicks property shows 2 only for the second MouseDown event; the first MouseDown Clicks property value is 1.
Figure 8-3. DoubleClick constituent events
8.2.1 Mouse Properties
In addition to the mouse events described earlier, several useful mouse related properties of the Control class are listed in Table 8-5.
Property |
Type |
Description |
---|---|---|
Capture |
Boolean |
Read/write. true if the control has captured the mouse. When captured, the control receives mouse input even if the mouse is not within the borders of the control. Typically the mouse is captured for you automatically while a mouse button is depressed (e.g., during drag operations). |
Cursor |
Cursor |
Read/write. The Cursor object to display when the mouse is over the control. The Cursor object is a member of the Cursors class, which provides a collection of Cursor objects (listed in Table 8-6). |
MouseButtons |
MouseButtons |
Read-only. Static (Shared in VB.NET) bitwise combination of values from MouseButtons enumeration (listed in Table 8-4). |
MousePosition |
Point |
Read-only. Static (Shared in VB.NET) point that contains the screen coordinates of the mouse cursor relative to the upper-left corner of the screen. Can use the Control PointToClient method to convert to client coordinates. |
ModifierKeys |
Keys |
Read-only. Static (shared in VB.NET) bitwise combination of Keys values, indicating status of Shift, Ctrl, and Alt keys. |
Many controls automatically change the mouse cursor as necessary. For example, when the cursor hovers over a Splitter control, the cursor changes to either the horizontal or vertical splitter symbol, as appropriate. If the mouse cursor hovers over any border of a Form, it will change to the appropriate resizing symbol.
You can use the Cursor property to control the mouse cursor that displays when the mouse cursor hot spot is over a control. The Cursor property is of type Cursor. The Cursor objects are provided by the Cursors class (note the plural), which contains a collection of Cursor objects. The members of the Cursors class are listed in Table 8-6. All Cursors except the panning and no-move cursors can have their appearance modified systemwide by going to Control Panel Mouse Pointers.
Member |
Default Appearance |
Description |
---|---|---|
AppStarting |
Cursor that appears when an application starts, typically a combination of an arrow and an hourglass. |
|
Arrow |
Arrow cursor. |
|
Cross |
Crosshair cursor. |
|
Default |
Default cursor, usually an arrow cursor. |
|
Hand |
Hand cursor, typically used when hovering over a link. |
|
Help |
Help cursor. |
|
HSplit |
Horizontal splitter cursor. |
|
IBeam |
I-beam cursor, usually used to represent a text cursor. |
|
No |
Cursor that indicates current region is invalid for current operation. |
|
NoMove2D |
Cursor used during wheel button operations when the mouse is not moving but the window can be scrolled both horizontally and vertically. |
|
NoMoveHoriz |
Cursor used during wheel operations when the mouse is not moving but the window can be scrolled horizontally. |
|
NoMoveVert |
Cursor used during wheel operations when the mouse is not moving but the window can be scrolled vertically. |
|
PanEast |
Cursor used during wheel operations when the mouse is moving and the window is scrolling horizontally to the right. |
|
PanNE |
Cursor used during wheel operations when the mouse is moving and the window is scrolling horizontally and vertically upward to the right. |
|
PanNorth |
Cursor used during wheel operations when the mouse is moving and the window is scrolling vertically upward. |
|
PanNW |
Cursor used during wheel operations when the mouse is moving and the window is scrolling horizontally and vertically upward to the left. |
|
PanSE |
Cursor used during wheel operations when the mouse is moving and the window is scrolling horizontally and vertically downward to the right. |
|
PanSouth |
Cursor used during wheel operations when the mouse is moving and the window is scrolling vertically downward. |
|
PanSW |
Cursor used during wheel operations when the mouse is moving and the window is scrolling horizontally and vertically downward to the left. |
|
PanWest |
Cursor used during wheel operations when the mouse is moving and the window is scrolling horizontally to the left. |
|
SizeAll |
Four-headed sizing cursor. |
|
SizeNESW |
Two-headed diagonal (northeast/southwest) sizing cursor. |
|
SizeNS |
Two-headed diagonal (north/south) sizing cursor. |
|
SizeNWSE |
Two-headed diagonal (northwest/southeast) sizing cursor. |
|
SizeWE |
Two-headed diagonal (west/east) sizing cursor. |
|
UpArrow |
UpArrow cursor, typically used to indicate an insertion point. |
|
VSplit |
Vertical splitter cursor. |
|
WaitCursor |
Wait cursor, typically an hourglass. |
The mouse properties are demonstrated in the MouseProperties program, listed in Example 8-7 (in C#) and in Example 8-8 (in VB.NET). The code that is different from the previous example is highlighted. When these examples are run, they look similar to the program shown previously in Figure 8-2.
Example 8-7. Mouse properties in C# (MouseProperties.cs)
using System; using System.Drawing; using System.Windows.Forms; namespace ProgrammingWinApps { public class MouseProperties : Form { private Label lbl; private Button btnReset; private TextBox txt; int i = 0; Cursor[ ] theCursors = {Cursors.AppStarting, Cursors.Arrow, Cursors.Hand, Cursors.Help, Cursors.No}; public MouseProperties( ) { Text = "Mouse Properties"; Size = new Size(400,600); btnReset = new Button( ); btnReset.Parent = this; btnReset.Location = new Point(250,50); btnReset.Text = "Reset"; btnReset.Click += new System.EventHandler(btnReset_Click); lbl = new Label( ); lbl.Parent = this; lbl.Location = new Point(50,50); lbl.Size = new Size(150,25); lbl.BorderStyle = BorderStyle.Fixed3D; lbl.MouseEnter += new System.EventHandler(lbl_MouseEnter); lbl.MouseHover += new System.EventHandler(lbl_MouseHover); lbl.MouseLeave += new System.EventHandler(lbl_MouseLeave); lbl.MouseDown += new System.Windows.Forms.MouseEventHandler(lbl_MouseDown); // Comment out to reduce quantity of text generated. // lbl.MouseMove += new // System.Windows.Forms.MouseEventHandler(lbl_MouseMove); lbl.MouseUp += new System.Windows.Forms.MouseEventHandler(lbl_MouseUp); lbl.MouseWheel += new System.Windows.Forms.MouseEventHandler(lbl_MouseWheel); lbl.Click += new System.EventHandler(lbl_Click); lbl.DoubleClick += new System.EventHandler(lbl_DoubleClick); txt = new TextBox( ); txt.Parent = this; txt.Location = new Point(50,90); txt.Size = new Size(300,475); txt.BorderStyle = BorderStyle.FixedSingle; txt.Multiline = true; txt.ScrollBars = ScrollBars.Vertical; } static void Main( ) { Application.Run(new MouseProperties( )); } private void btnReset_Click(object sender, EventArgs e) { lbl.Text = ""; txt.Text = ""; } private void lbl_MouseEnter(object sender, EventArgs e) { lbl.Text = "MouseEnter"; EventArgsStrings( ); TextBoxDraw("Label MouseEnter"); lbl.Cursor = Cursors.WaitCursor; } private void lbl_MouseHover(object sender, EventArgs e) { lbl.Cursor = theCursors[i % 5]; i++; lbl.Text = "MouseHover"; EventArgsStrings( ); TextBoxDraw("Label MouseHover"); } private void lbl_MouseLeave(object sender, EventArgs e) { lbl.Text = "MouseLeave"; EventArgsStrings( ); TextBoxDraw("Label MouseLeave"); } private void lbl_MouseDown(object sender, MouseEventArgs e) { lbl.Text = "MouseDown"; MouseEventArgsStrings(e); TextBoxDraw("Label MouseDown"); } private void lbl_MouseMove(object sender, MouseEventArgs e) { lbl.Text = "MouseMove"; MouseEventArgsStrings(e); TextBoxDraw("Label MouseMove"); } private void lbl_MouseUp(object sender, MouseEventArgs e) { lbl.Text = "MouseUp"; MouseEventArgsStrings(e); TextBoxDraw("Label MouseUp"); } private void lbl_MouseWheel(object sender, MouseEventArgs e) { lbl.Text = "MouseWheel"; MouseEventArgsStrings(e); TextBoxDraw("Label MouseWheel"); } private void lbl_Click(object sender, EventArgs e) { lbl.Text = "Click"; EventArgsStrings( ); TextBoxDraw("Label Click"); } private void lbl_DoubleClick(object sender, EventArgs e) { lbl.Text = "DoubleClick"; EventArgsStrings( ); TextBoxDraw("Label DoubleClick"); } private void EventArgsStrings( ) { string str; str = " Cursor: " + lbl.Cursor.ToString( ); str += " Capture: " + lbl.Capture.ToString( ); str += " MouseButtons: " + MouseButtons.ToString( ); str += " MousePosition: " + MousePosition.ToString( ); str += " ModifierKeys: " + ModifierKeys.ToString( ); TextBoxDraw(str); } private void MouseEventArgsStrings(MouseEventArgs e) { string str; str = " Button: " + e.Button.ToString( ); str += " Clicks: " + e.Clicks.ToString( ); str += " Delta: " + e.Delta.ToString( ); str += " X: " + e.X.ToString( ); str += " Y: " + e.Y.ToString( ); TextBoxDraw(str); EventArgsStrings( ); } private void TextBoxDraw(string str) { txt.AppendText(str); } } }
Example 8-8. Mouse properties in VB.NET (MouseProperties.vb)
Option Strict On imports System imports System.Drawing imports System.Windows.Forms namespace ProgrammingWinApps public class MouseProperties : inherits Form private lbl as Label private WithEvents btnReset as Button private txt as TextBox dim i as integer = 0 dim theCursors as Cursor( ) = {Cursors.AppStarting, _ Cursors.Arrow, _ Cursors.Hand, _ Cursors.Help, _ Cursors.No} public sub New( ) Text = "Mouse Properties" Size = new Size(400,600) btnReset = new Button( ) btnReset.Parent = me btnReset.Location = new Point(250,50) btnReset.Text = "Reset" lbl = new Label( ) lbl.Parent = me lbl.Location = new Point(50,50) lbl.Size = new Size(150,25) lbl.BorderStyle = BorderStyle.Fixed3D AddHandler lbl.MouseEnter, AddressOf lbl_MouseEnter AddHandler lbl.MouseHover, AddressOf lbl_MouseHover AddHandler lbl.MouseLeave, AddressOf lbl_MouseLeave AddHandler lbl.MouseDown, AddressOf lbl_MouseDown ' Comment out to reduce quantity of text generated. ' AddHandler lbl.MouseMove, AddressOf lbl_MouseMove AddHandler lbl.MouseUp, AddressOf lbl_MouseUp AddHandler lbl.MouseWheel, AddressOf lbl_MouseWheel AddHandler lbl.Click, AddressOf lbl_Click AddHandler lbl.DoubleClick, AddressOf lbl_DoubleClick txt = new TextBox( ) txt.Parent = me txt.Location = new Point(50,90) txt.Size = new Size(300,475) txt.BorderStyle = BorderStyle.FixedSingle txt.Multiline = true txt.ScrollBars = ScrollBars.Vertical end sub public shared sub Main( ) Application.Run(new MouseProperties( )) end sub private sub btnReset_Click(ByVal sender as object, _ ByVal e as EventArgs) _ Handles btnReset.Click lbl.Text = "" txt.Text = "" end sub private sub lbl_MouseEnter(ByVal sender as object, _ ByVal e as EventArgs) lbl.Text = "MouseEnter" EventArgsStrings( ) TextBoxDraw("Label MouseEnter") end sub private sub lbl_MouseHover(ByVal sender as object, _ ByVal e as EventArgs) lbl.Cursor = theCursors(i mod 5) i = i + 1 lbl.Text = "MouseHover" EventArgsStrings( ) TextBoxDraw("Label MouseHover") end sub private sub lbl_MouseLeave(ByVal sender as object, _ ByVal e as EventArgs) lbl.Text = "MouseLeave" EventArgsStrings( ) TextBoxDraw("Label MouseLeave") end sub private sub lbl_MouseDown(ByVal sender as object, _ ByVal e as MouseEventArgs) lbl.Text = "MouseDown" MouseEventArgsStrings(e) TextBoxDraw("Label MouseDown") end sub private sub lbl_MouseMove(ByVal sender as object, _ ByVal e as MouseEventArgs) lbl.Text = "MouseMove" MouseEventArgsStrings(e) TextBoxDraw("Label MouseMove") end sub private sub lbl_MouseUp(ByVal sender as object, _ ByVal e as MouseEventArgs) lbl.Text = "MouseUp" MouseEventArgsStrings(e) TextBoxDraw("Label MouseUp") end sub private sub lbl_MouseWheel(ByVal sender as object, _ ByVal e as MouseEventArgs) lbl.Text = "MouseWheel" MouseEventArgsStrings(e) TextBoxDraw("Label MouseWheel") end sub private sub lbl_Click(ByVal sender as object, _ ByVal e as EventArgs) lbl.Text = "Click" EventArgsStrings( ) TextBoxDraw("Label Click") end sub private sub lbl_DoubleClick(ByVal sender as object, _ ByVal e as EventArgs) lbl.Text = "DoubleClick" EventArgsStrings( ) TextBoxDraw("Label DoubleClick") end sub private sub EventArgsStrings( ) dim str as string str = vbTab + "Cursor: " + _ lbl.Cursor.ToString( ) str = str + vbNewLine + vbTab + "Capture: " + _ lbl.Capture.ToString( ) str = str + vbNewLine + vbTab + "MouseButtons: " + _ MouseButtons.ToString( ) str = str + vbNewLine + vbTab + "MousePosition: " + _ MousePosition.ToString( ) str = str + vbNewLine + vbTab + "ModifierKeys: " + _ ModifierKeys.ToString( ) TextBoxDraw(str) end sub private sub MouseEventArgsStrings(ByVal e as MouseEventArgs) dim str as string str = vbTab + "Button: " + e.Button.ToString( ) str = str + vbNewLine + vbTab + "Clicks: " + e.Clicks.ToString( ) str = str + vbNewLine + vbTab + "Delta: " + e.Delta.ToString( ) str = str + vbNewLine + vbTab + "X: " + e.X.ToString( ) str = str + vbNewLine + vbTab + "Y: " + e.Y.ToString( ) TextBoxDraw(str) EventArgsStrings( ) end sub private sub TextBoxDraw(str as string) txt.AppendText(vbNewLine + str) end sub end class end namespace
In the code in Example 8-7 and Example 8-8, the program creates a member array of Cursor objects:
Cursor[ ] theCursors = {Cursors.AppStarting, Cursors.Arrow, Cursors.Hand, Cursors.Help, Cursors.No};
dim theCursors as Cursor( ) = {Cursors.AppStarting, _ Cursors.Arrow, _ Cursors.Hand, _ Cursors.Help, _ Cursors.No}
This program uses only five different Cursor objects in the array. They are displayed in succession in the MouseHover event, using the member variable i as a counter, in conjunction with the modulus operator, to index into the array:
private void lbl_MouseHover(object sender, EventArgs e) { lbl.Cursor = theCursors[i % 5]; i++; lbl.Text = "MouseHover"; EventArgsStrings( ); TextBoxDraw("Label MouseHover"); }
private sub lbl_MouseHover(ByVal sender as object, _ ByVal e as EventArgs) lbl.Cursor = theCursors(i mod 5) i = i + 1 lbl.Text = "MouseHover" EventArgsStrings( ) TextBoxDraw("Label MouseHover") end sub
Each event trapped in this program displays the same information as in the previous example, plus the values of the mouse properties. This example is refined a bit from the previous example by moving all the common code for constructing the display string into helper methods. There are two of these helper methods: EventArgsStrings, which takes no arguments, and MouseEventArgsStrings, which takes the MouseEventArgs as an argument. Here are these two methods:
private void EventArgsStrings( ) { string str; str = " Cursor: " + lbl.Cursor.ToString( ); str += " Capture: " + lbl.Capture.ToString( ); str += " MouseButtons: " + MouseButtons.ToString( ); str += " MousePosition: " + MousePosition.ToString( ); str += " ModifierKeys: " + ModifierKeys.ToString( ); TextBoxDraw(str); } private void MouseEventArgsStrings(MouseEventArgs e) { string str; str = " Button: " + e.Button.ToString( ); str += " Clicks: " + e.Clicks.ToString( ); str += " Delta: " + e.Delta.ToString( ); str += " X: " + e.X.ToString( ); str += " Y: " + e.Y.ToString( ); TextBoxDraw(str); EventArgsStrings( ); }
private sub EventArgsStrings( ) dim str as string str = vbTab + "Cursor: " + _ lbl.Cursor.ToString( ) str = str + vbNewLine + vbTab + "Capture: " + _ lbl.Capture.ToString( ) str = str + vbNewLine + vbTab + "MouseButtons: " + _ MouseButtons.ToString( ) str = str + vbNewLine + vbTab + "MousePosition: " + _ MousePosition.ToString( ) str = str + vbNewLine + vbTab + "ModifierKeys: " + _ ModifierKeys.ToString( ) TextBoxDraw(str) end sub private sub MouseEventArgsStrings(ByVal e as MouseEventArgs) dim str as string str = vbTab + "Button: " + e.Button.ToString( ) str = str + vbNewLine + vbTab + "Clicks: " + e.Clicks.ToString( ) str = str + vbNewLine + vbTab + "Delta: " + e.Delta.ToString( ) str = str + vbNewLine + vbTab + "X: " + e.X.ToString( ) str = str + vbNewLine + vbTab + "Y: " + e.Y.ToString( ) TextBoxDraw(str) EventArgsStrings( ) end sub
Windows Forms and the .NET Framework
Getting Started
Visual Studio .NET
Events
Windows Forms
Dialog Boxes
Controls: The Base Class
Mouse Interaction
Text and Fonts
Drawing and GDI+
Labels and Buttons
Text Controls
Other Basic Controls
TreeView and ListView
List Controls
Date and Time Controls
Custom Controls
Menus and Bars
ADO.NET
Updating ADO.NET
Exceptions and Debugging
Configuration and Deployment