Option Explicit
Public WithEvents cmb As CommandButton
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Type MSG
hwnd As Long
message As Long
wParam As Long
lParam As Long
time As Long
pt As POINTAPI
End Type
Private Declare Function PeekMessage Lib "user32" _
Alias "PeekMessageA" _
(ByRef lpMsg As MSG, ByVal hwnd As Long, _
ByVal wMsgFilterMin As Long, _
ByVal wMsgFilterMax As Long, _
ByVal wRemoveMsg As Long) As Long
Private Declare Function WaitMessage Lib "user32" _
() As Long
Private Declare Function PostMessage Lib "user32.dll" _
Alias "PostMessageA" (ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Private Declare Function GetCursorPos Lib "user32.dll" _
(ByRef lpPoint As POINTAPI) As Long
Private Declare Function SetCursor Lib "user32" _
(ByVal hCursor As Long) As Long
Private Declare Function LoadCursor Lib "user32.dll" _
Alias "LoadCursorA" _
(ByVal hInstance As Long, _
ByVal lpCursorName As Long) As Long
Private Declare Function FindWindow Lib "user32.dll" _
Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function WindowFromPoint Lib "user32" _
(ByVal xPoint As Long, ByVal yPoint As Long) As Long
Private Const PM_NOREMOVE As Long = &H0
Private Const WM_SETCURSOR As Long = &H20
Private bMouseHooked As Boolean
Private bStop As Boolean
Private bCurOverButton As Boolean
Private lCur As Long
Private oFrm As UserForm
Public Sub ChangeCurOf(frm As UserForm, ByVal Button As CommandButton, ByVal Cur As Long)
Dim tMsg As MSG
Dim tPt As POINTAPI
Dim lCurID As Long
Dim hwnd As Long
If bMouseHooked Then Exit Sub
bMouseHooked = True
bStop = False
lCur = Cur
Set oFrm = frm
hwnd = _
FindWindow(vbNullString, frm.Caption)
If Not bCurOverButton Then Exit Sub
Do
GetCursorPos tPt
If WindowFromPoint(tPt.X, tPt.Y) <> hwnd Then bStop = True
SetCursor LoadCursor(0, Cur)
WaitMessage
If PeekMessage _
(tMsg, hwnd, _
WM_SETCURSOR, WM_SETCURSOR, PM_NOREMOVE) Then
PostMessage hwnd, WM_SETCURSOR, 0, 0
End If
DoEvents
Loop Until bStop
End Sub
Private Sub cmb_MouseMove(ByVal Button As Integer, _
ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
bStop = True
bMouseHooked = False
bCurOverButton = True
Call ChangeCurOf(oFrm, cmb, lCur)
End Sub