Is the mouse over a component? Was a mouse button pressed? Which button was it? Did the user release a button, which one? Exactly where inside the form is the mouse? Did the user move the mouse out of the form and into another?
Delphi (as Windows) constantly monitors what the user is doing with the mouse. Naturally, Delphi can detect any mouse action. When a Delphi application detects a mouse action, it calls whatever event handler we've defined for the corresponding event.
Responding to the mouseThere are four kinds of mouse actions you can respond to in your applications. Three of these are uniquely mouse actions: mouse-button down, mouse moved, and mouse-button up. The fourth kind of action, a click (a complete press-and-release, all in one place) is a bit different, as it can also be generated by some kinds of keystrokes (such as pressing Enter in a modal dialog box).
Components recognize a mouse event only when the mouse pointer is inside the component. However, if a mouse button is pressed and held while the mouse pointer is inside a component or form, that object captures the mouse. This means that no other Delphi object can react to mouse events until the user releases the mouse button, regardless of where the user moves the mouse.
There are three fundamental mouse event handlers: OnMouseDown, OnMouseMove, and OnMouseUp. The MouseUp and MouseDown event handlers take the same five parameters as follows (the MouseMove lacks a Button parameter):
- Sender - The object that detected the mouse action.
- Button - Indicates which mouse button was involved: mbLeft, mbMiddle, or mbRight.
- Shift - Indicates the state of the Alt, Ctrl, and Shift keys and the state of the mouse buttons when the event occurred.
- X, Y - The pixel coordinates of the mouse pointer in the client area of the Sender.
OnMouseDown/OnMouseUpWhenever the user presses a button on the mouse, an OnMouseDown event goes to the object the pointer is over. To see the event handler at work, assign the following code to the OnMouseDown procedure:
When the application runs, you can press the mouse button with the mouse cursor on the form and have the circle appear at the point clicked. This simple event uses the X and Y parameters sent to the method, and calls the Ellipse method of the canvas to display the circle.
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) ; begin Canvas.Ellipse(x-20,y-20,x+20,y+20) ; end;
Let's spice this code a bit. Suppose that we want red colored circles when the user presses the left mouse button, and blue colored rectangles when right button is pressed. The Button argument has three predefined constants to determine which button was pressed: mbLeft, mbRight, mbMiddle:
As for the OnMouseUp event: use the OnMouseUp event handler to implement special processing when the user releases a mouse button.
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) ; begin case Button of mbLeft: begin Canvas.Brush.Color := clRed; Canvas.Ellipse(x-20,y-20,x+20,y+20) ; end; mbRight: begin Canvas.Brush.Color := clBlue; Canvas.Rectangle(x-20,y-20,x+20,y+20) ; end; end; end;
OnMouseMoveOnMouseMove occurs when the user moves the mouse pointer while the mouse pointer is over a control. Since the OnMouseMove event handler will be called relatively frequently, any code inside this event handler will be executed often.
As we know, we can combine the keyboard with the mouse. For example, we can have the Shift-Move combination draw a circle. Let's see MouseMove in action (new project/new form):
With this code, moving the mouse over the form causes circles to follow the mouse if Shift key was pressed during move, and rectangles if Ctrl key was pressed
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer) ; begin if ssShift in Shift then Canvas.Ellipse(x-20,y-20,x+20,y+20) else if ssCtrl in Shift then Canvas.Rectangle(x-20,y-20,x+20,y+20) ; end;