Code Archive - Cursors - Confine the Cursor

Another useful feature of the Windows API is the ability to restrict mouse movement inside a certain rectangle. This code doesn't have quite as many uses as some other code, but some applications can include restricting the mouse during Drag-and-Drop operations, or during some activity where you don't want the user to accidentally lose focus of a window (also useful in windowed games.)

Constricting the Cursor

To constrict the cursor, you will need the API ClipCursor, and associating UDTs as declared below.

Declare Function ClipCursor Lib "User32" (lpRect As RECT) As Long

Type RECT
   Left as Long
   Top as Long
   Right as Long
   Bottom as Long
End Type

All you have to do for this is fill the values of the RECT structure, and then call the API, passing the structure with the lpRect argument. Note that VB will not let you pass UDTs ByVal, so don't even try.

WARNING: This setting is system wide! If you program unexpectedly quits, the cursor will not be freed, and the user will not have any way to free it without another program!

Freeing the Cursor

There are several ways to clear the constricted region. One method is to find the rectangle of the desktop window, and then confine the cursor to that window. However, as defined in the Windows SDK, if you pass a NULL value for the RECT argument, Windows will clear the clipping region. The advantages of doing this is that the code is smaller (one line vs. three or four), is more consise, and will be easier to execute from the Immediate Window in case of a run-time error.

The trick of this though is VB's type checking. VB will not let you pass a NULL (or zero) value for a UDT. To work around this, you can create a second API declare, but modifying the argument to change the type to a Long. We declare this using the Alias keyword to differentiate between the other API declare. The corrected declare is as follows:

Declare Function ClipCursorClear Lib "User32" Alias "ClipCursor" (lpRect As Long) As Long

To clear the cursor, you will just need to use this one line of code:

ClipCursorClear 0