I’m still using Microsoft Access 2002 and thought I’d share this little tip. You know how in web browsers hyperlinks are underlined in blue and your cursor changes to a little hand when you move over them?
Using a slightly bizarre but agreeable undocumented feature you can emulate the cursor change in Microsoft Access 2002.
Now you’d think that you would be able to use the Screen.MousePointer function. However, that doesn’t provide access to the hyperlink hand. Also, brilliantly, if you attempt to replicate this using the built-in Screen.MousePointer function (using “=Screen.MousePointer(11)” in the MouseMove event), you can corrupt your database and crash Microsoft Access! WOW! Now that’s what I call an undocumented feature. You would also think that you could instead place the Screen.MousePointer command in an Event Procedure on the MouseMove event but that simply changes the cursor to a hand until you change it back in code somewhere else.
Example of how to use
This is really simple and works beautifully.
- Create a module called “Cursor” and paste the code below into it.
- Create a form and place a label in the middle.
- Type any caption for the label. Set the label ForeColor to blue and turn FontUnderline on.
- Set the MouseMove event to “=UseHand()”
- Save and switch to form view. Move your cursor around the form.
Notice how when you move over the label the cursor changes to a hand and, here’s the undocumented feature aspect, when you move away from the label, it changes back to the normal cursor without any VBA assistance!
In real life
I’ve been using this technique instead of command buttons for buttons that would open a new page or a new form. It really makes your screen feel much less cluttered and provides a user interface that is now much more familiar (web browsers) to users than buttons.
Brilliantly, this also works in continuous forms without any adjustments.
This is a screenshot showing a continuous form on the upper right with a single form on the lower right (that is linked to the continuous)hosted in a single form. There are hyperlink controls on the host form (Products, People, etc), a hyperlink control on the single linked form and on the continuous form. The cursor changes to a hand over all the blue underlined labels and back again everywhere else. Imagine how cluttered this would appear with command buttons. Click the screenshot for the full view.
Option Compare Database
' Control the look of the cursor
' Replacement for Screen.MousePointer function
' Standard cursor IDs
Public Enum SystemCursorID
IDC_arrow = 32512&
IDC_IBEAM = 32513&
IDC_WAIT = 32514&
IDC_CROSS = 32515&
IDC_UPARROW = 32516&
IDC_SIZE = 32640& ' OBSOLETE: use IDC_SIZEALL
IDC_ICON = 32641& ' OBSOLETE: use IDC_ARROW
IDC_SIZENWSE = 32642&
IDC_SIZENESW = 32643&
IDC_SIZEWE = 32644&
IDC_SIZENS = 32645&
IDC_SIZEALL = 32646&
IDC_NO = 32648& ' not in win3.1
IDC_HAND = 32649&
IDC_APPSTARTING = 32650& ' not in win3.1
IDC_HELP = 32651&
Private Type POINT ' declared here because a point is a rectangle of 1 unit width and eight
X As Long
Y As Long
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
Private Declare Function LoadCursor Lib "user32" Alias "LoadCursorA" ( _
ByVal hInstance As Long, _
ByVal pCursorName As Long) As Long
Private Declare Function ShowCursor Lib "user32" ( _
ByVal bShow As Long) As Long
Private Declare Function SetCursorPos Lib "user32" ( _
ByVal X As Long, _
ByVal Y As Long) As Long
Private Declare Function SetCursor Lib "user32" ( _
ByVal hCursor As Long) As Long
Private Declare Function GetCursorPos Lib "user32" ( _
lpPoint As POINT) As Long
Private Declare Function ClipCursor Lib "user32" ( _
lpRect As Any) As Long
Private Declare Function GetCursor Lib "user32" () As Long
Private Declare Function GetClipCursor Lib "user32" ( _
lprc As RECT) As Long
Dim hLastCursor As Long
''' Changes cursors to a hand, normally used to indicate the item below the cursor
''' is a link that can be followed.
''' Call in the OnMouseMove Event (instead of calling an [Event Procedure]) of a label
''' to change the cursor to a hand. Doing it this way seems to reset the cursor back to
''' default when you move out of the control's area. Miraculous!
Public Function UseHand()
' Sets the cursor to a system shape
Public Function UseSystemCursor(CursorID As SystemCursorID)
' Load new cursor and, if successful, set
hLastCursor = LoadCursor(0, CLng(CursorID))
If (hLastCursor > 0) Then
hLastCursor = SetCursor(hLastCursor)
' Undoes the last cursor change
Public Sub RestoreCursor()
If hLastCursor > 0 Then
hLastCursor = 0
In later versions of Access and if you are using a control with the Hyperlink Address property, you no longer need this workaround. Simply put a single space in the HyperlinkAddress property. Oddly, it uses a different hand to the system-wide hand cursor. Everywhere you go with Access, you keep running into undocumented features!