In the previous article we have seen how to handle some basic mouse events like MouseUp/MouseDown and MouseMove. However, there are times when you want your mouse to do what you tell it.
'Basic' API stuff
Many of us write programs that are designed to work only with the mouse. If we are writing programs that require mouse presence and/or are dependent on mouse we have to be sure that various things are set up the right way.Is Mouse Present?
The quickest way to see if the mouse is present:procedure TForm1.FormCreate(Sender: TObject) ;
begin
if GetSystemMetrics(SM_MOUSEPRESENT) <> 0 then
ShowMessage('Mouse present')
else
ShowMessage('Mouse NOT present') ;
end;
Animated Mouse Cursor
Here's how to use animated cursors (or even how to use a BMP as a CUR):procedure TForm1.Button1Click(Sender: TObject) ;
const MyCursor = 1;
begin
Screen.Cursors[MyCursor] :=
LoadCursorFromFile
('c:\windows\cursors\globe.ani') ;
Form1.Cursor := MyCursor;
end;
Positioning the mouse
The SetCursorPos API function moves the cursor to the specified screen coordinates. Since this function does not get a windows handle as a parameter, x/y have to be screen coordinates. Your component does use relative coordinates, e.g. relative to a TForm. You have to use the ClientToScreen function to calculate the proper screen coordinates.procedure SetMousePos(x, y: longint) ;
var pt: TPoint;
begin
pt := ClientToScreen(point(x, y)) ;
SetCursorPos(pt.x, pt.y) ;
end;
Simulations
On most occasions we want mouse to move to a certain position on the screen. We know that some components do not respond to a cursor change until the user moves the mouse, we have to provide some small move-from-code technique. And what about simulation mouse clicks without calling the OnClick event handler?procedure TForm1.Button1Click(Sender: TObject) ;The following example will simulate mouse click event on Button2 after the click to Button1. We have to use mouse_event() API call. The mouse_event function synthesizes mouse motion and button clicks. Mouse coordinates given are in "Mickeys", where their are 65535 "Mickeys" to a screen's width.
var pt : TPoint;
begin
Application.ProcessMessages;
Screen.Cursor := crHourglass;
GetCursorPos(pt) ;
SetCursorPos(pt.x + 1, pt.y + 1) ;
Application.ProcessMessages;
SetCursorPos(pt.x - 1, pt.y - 1) ;
Screen.Cursor := crArrow
end;
//simulating mouse click
//we need 2 buttons on the form
procedure TForm1.Button1Click(Sender: TObject) ;
var
Pt : TPoint;
begin
Application.ProcessMessages;
{Get the point in the center of Button 2}
Pt.x := Button2.Left + (Button2.Width div 2) ;
Pt.y := Button2.Top + (Button2.Height div 2) ;
{Convert Pt to screen coordinates and Mickeys}
Pt := ClientToScreen(Pt) ;
Pt.x := Round(Pt.x * (65535 / Screen.Width)) ;
Pt.y := Round(Pt.y * (65535 / Screen.Height)) ;
{Simulate the mouse move}
Mouse_Event(MOUSEEVENTF_ABSOLUTE or
MOUSEEVENTF_MOVE,
Pt.x, Pt.y, 0, 0) ;
{Simulate the left mouse button down}
Mouse_Event(MOUSEEVENTF_ABSOLUTE or
MOUSEEVENTF_LEFTDOWN,
Pt.x, Pt.y, 0, 0) ;;
{Simulate the left mouse button up}
Mouse_Event(MOUSEEVENTF_ABSOLUTE or
MOUSEEVENTF_LEFTUP,
Pt.x, Pt.y, 0, 0) ;;
end;
Restrict The Mouse Movement
Using the Windows API function ClipCursor, it is possible to restrict the movement of the mouse to a specific rectangular region on the screen:procedure TForm1.FormCreate(Sender: TObject) ;
var r : TRect;
begin
//it would be a good idea to move the
//mouse inside the form before restriction
r := BoundsRect;
ClipCursor(@R) ;
end;
procedure TForm1.FormClick(Sender: TObject) ;
begin
//always be sure to release the cursor
ClipCursor(nil) ;
end;


