You’d like to be able to restrict mouse-cursor movement to certain areas of the current form. You think it would help users of your application if the mouse stays where it needs to be until they’re done with it. How can you limit mouse movement in Access?
The Windows API’s ClipCursor subroutine will limit the movement of the mouse to a single form or region on a form, as you’ll see in this solution.
To try out this technique, load and run the frmClip form from
11-04.MDB
. This form, shown in Figure 11-5, limits the mouse movement to the area of the
form once you click the large button. If you click the button again
or close the form, code attached to either event frees the mouse
cursor to move anywhere on the screen. If you move the form, Windows
frees the mouse cursor for you.
To use this technique in your own applications, follow these steps:
Import the module basClipCursor from 11-04.MDB
.
This module contains the function declarations and user-defined types
that you’ll need.
To limit the mouse to a single form, you’ll need to get the
form coordinates and tell Windows to use those coordinates as limits
for the mouse. To do this, you’ll need code something like the
following (because this code fragment uses Me
, it
must be in a form’s module, not a global module):
Dim typRect as acb_tagRect Call acb_apiGetWindowRect (Me.Hwnd, typRect) Call acb_apiClipCursor(typRect)
To free the mouse cursor, use code like this:
Call acb_apiClipCursor(ByVal vbNullString)
See Section 11.4.3 for an example.
The
ClipCursor API routine (aliased as
acb_apiClipCursor in the code) expects as its
only parameter a user-defined data type consisting of four long
integers representing coordinates of a rectangle. This data type has
been declared for you in basClipCursor as
acb_tagRect
. This is a common data structure, used
often with API routines that interact with the screen or printer. It
is defined as follows:
Type acb_tagRect lngLeft As Long lngTop As Long lngRight As Long lngBottom As Long End Type
When
you want to restrict mouse movement, you’ll need to retrieve
the coordinates of the current form. You can accomplish this by
calling the GetWindowRect API function (aliased
as acb_apiGetWindowRect in the code), which will
fill in an acb_tagRect
structure with the left,
top, right, and bottom coordinates of the window whose handle you
pass it. Therefore, by calling
acb_apiGetWindowRect with the handle of the
current form, you’ll retrieve the coordinates of that form in
pixels:
Dim typRect as acb_tagRect Call acb_apiGetWindowRect (Me.hWnd, typRect)
Once you’ve got a structure containing the coordinates of the current form, you can call ClipCursor and pass that filled-in structure to it. The sample form combines these API calls, as shown here:
Private Sub cmdClip_Click( ) Dim typRect As acb_tagRect Static sstrCaption As String ' Static variable to keep track of clipping Static fClip As Boolean If fClip Then Me!cmdClip.Caption = sstrCaption Call acb_apiClipCursor(ByVal vbNullString) Else sstrCaption = Me!cmdClip.Caption Me!cmdClip.Caption = "Free the Mouse!" Call acb_apiGetWindowRect(Me.hWnd, typRect) Call acb_apiClipCursor(typRect) End If fClip = Not fClip End Sub
In the sample routine, which is executed each time you click the
large button on frmClip, fClip
alternates
between True
and False
, keeping
track of whether mouse clipping is currently in effect. If it is, the
routine calls acb_apiClipCursor to disable
clipping and resets the button’s caption. If clipping is not in
effect, the routine stores away the original caption, sets a new one
(“Free the Mouse!”), retrieves the form’s
coordinates, and finally calls acb_apiClipCursor
to restrict the cursor’s movement.
To end
the mouse-cursor restrictions, send a null value to
acb_apiClipCursor. To do that, pass the
vbNullString
intrinsic constant by value. Because
the acb_apiClipCursor procedure has been
declared to accept any type of parameter, you can send it a structure
in one call and a null value in another.
The method presented in this solution is not foolproof in Access. You’re taking control of a feature that Access normally controls itself, and sometimes the interaction may be unpredictable. In this case, if you restrict the mouse movement to a single form, but then use the mouse to move or resize the form, Access will free the mouse for you. Therefore, if you want to force users to stay on a single form, you’re better off using a modal form instead. If, on the other hand, you’re just trying to ensure that the mouse remains in the area of the form where the users need it to be, the method described here is appropriate. Restricting the mouse movement is not meant for every application, but if you want to help your users out a little, try it.