At some point, you may find it useful to manipulate the location of the mouse cursor. Perhaps you are
designing an interactive tutorial, a walkthrough, or maybe you plan on controlling another application
through mouse events. Regardless, you will quickly find a number of hurdles to overcome and it is the
goal of this example to help you over, under, or around these hurdle
Assumes
First, a little bit of background about the mouse in general. Since the days of DOS, mouse drivers have
reported their location in graphic applications by returning X/Y coordinates based up on a resolution
independent coordinate system. This coordinate system neatly breaks the screen down into 65535
units on each axis. A unit of measurement in this system is known as a Mickey. This system was
devised to insure that the specification for mouse drivers would be a lasting one, and that screen
resolution would never overtake the resolution of the mouse driver.
Why mention this? Well, the Win32 API function call which allows you to specify the location for the
mouse wants the location provided in mickeys. And the first hurdle to overcome is converting screen
coordinates to mouse coordinates.
In order to make the coversion, we first need to get the screen's height and width with
GetSystemMetrics. The GetScreenRes subroutine illustrates how this is done.
Once the resolution of the display is known, we can convert the pixels returned by GetScreenRes into
mickeys. There are four conversion routines included with this example, two to handle pixel
conversions to mickeys (PixelXToMickey, PixelYToMickey), and two to handle mickey to pixel
conversions (MickeyXToPixel, MickeyYToPixel).
Now that we have conversion routines, we can actually do some work. Included with this example is
CenterMouseOn, a function that will center the mouse cursor on anything that has an hWnd. An
example of using this function to put the cursor over a commandbutton appears as:
CenterMouseOn (command1.hWnd)
If you need to move the mouse but don't have an hWnd to reference, the MouseMove function will
allow you to specify an X/Y coordinate for the mouse cursor. And once it is moved, you can use the
MouseFullClick function to simulate a mouseclick.
Side Effects
There are a series of mouse coordinate to screen coordinate routines included in this example. Due to
rounding problems, it is quite likely that the calculations may be off by a pixel. If your application
requires extremely precise pointer placement, you may want to develop or look for a more precise
method.
One of the uglier portions of this code are the mickey to pixel routines. They use a series of
temporary singles to store values prior to being converted. This was done to improve the accuracy of
the conversion, but even so, rounding errors continue to creep in. If you know of a better, more
accurate way to accomplish the same task, I would appreciate hearing about it.
API Declarations' ----------------------------------------------
' * MouseEvent Related Declares *
' ----------------------------------------------
Private Const MOUSEEVENTF_ABSOLUTE = &H8000
Private Const MOUSEEVENTF_LEFTDOWN = &H2
Private Const MOUSEEVENTF_LEFTUP = &H4
Private Const MOUSEEVENTF_MIDDLEDOWN = &H20
Private Const MOUSEEVENTF_MIDDLEUP = &H40
Private Const MOUSEEVENTF_MOVE = &H1
Private Const MOUSEEVENTF_RIGHTDOWN = &H8
Private Const MOUSEEVENTF_RIGHTUP = &H10
Private Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, _
ByVal dx As Long, ByVal dy As Long, ByVal cbuttons As Long, _
ByVal dwExtraInfo As Long)
' ----------------------------------------------
' * GetSystemMetrics Related Declares *
' ----------------------------------------------
Private Const SM_CXSCREEN = 0
Private Const SM_CYSCREEN = 1
Private Const TWIPS_PER_INCH = 1440
Private Const POINTS_PER_INCH = 72
Private Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex _
As Long) As Long
' ----------------------------------------------
' * GetWindowRect Related Declares *
' ----------------------------------------------
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, _
lpRect As RECT) As Long
' ----------------------------------------------
' * Internal Constants and Types *
' ----------------------------------------------
Private Const MOUSE_MICKEYS = 65535
Public Enum enReportStyle
rsPixels
rsTwips
rsInches
rsPoints
End Enum
Public Enum enButtonToClick
btcLeft
btcRight
btcMiddle
End Enum