Option Explicit
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type MSLLHOOKSTRUCT
pt As POINTAPI
mousedata As Long
flags As Long
time As Long
dwExtraInfo As Long
End Type
Private Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" _
(ByVal Destination As Long, _
ByVal Source As Long, _
ByVal Length As Long)
Private Declare Function FindWindow Lib "user32.dll" _
Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function GetWindowLong Lib "user32" _
Alias "GetWindowLongA" ( _
ByVal hwnd As Long, _
ByVal nIndex As Long) As Long
Private Declare Function SetWindowsHookEx Lib _
"user32" _
Alias "SetWindowsHookExA" _
(ByVal idHook As Long, _
ByVal lpfn As Long, _
ByVal hmod As Long, _
ByVal dwThreadId As Long) As Long
Private Declare Function CallNextHookEx Lib "user32" _
(ByVal hHook As Long, _
ByVal nCode As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" _
(ByVal hHook As Long) As Long
Private Const HC_ACTION = 0
Private Const WH_MOUSE_LL = 14
Private Const WM_MOUSEWHEEL = &H20A
Private Const GWL_HINSTANCE = (-6)
Private uParamStruct As MSLLHOOKSTRUCT
Private oObject As Object
Private lLowLevelMouse As Long
Private bHooked As Boolean
'====================='
'\\ Public Routines '
'====================='
Public Property Let MakeScrollableWithMouseWheel _
(ByVal Obj As Object, ByVal vNewValue As Boolean)
If vNewValue Then
Hook_Mouse
Else
UnHook_Mouse
End If
Set oObject = Obj
bHooked = vNewValue
End Property
Public Property Get MakeScrollableWithMouseWheel _
(ByVal Obj As Object) As Boolean
MakeScrollableWithMouseWheel = bHooked
End Property
'====================='
'\\ Private Routines '
'====================='
Function LowLevelMouseProc _
(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Static iTopIndex As Integer
On Error Resume Next
If (nCode = HC_ACTION) Then
If wParam = WM_MOUSEWHEEL Then
With oObject
If GetHookStruct(lParam).mousedata > 0 Then
.TopIndex = iTopIndex - 1
iTopIndex = .TopIndex
Else
.TopIndex = iTopIndex + 1
iTopIndex = .TopIndex
End If
End With
LowLevelMouseProc = -1
Exit Function
End If
End If
LowLevelMouseProc = _
CallNextHookEx(lLowLevelMouse, nCode, wParam, ByVal lParam)
End Function
Private Function GetHookStruct(ByVal lParam As Long) As MSLLHOOKSTRUCT
CopyMemory VarPtr(uParamStruct), lParam, LenB(uParamStruct)
GetHookStruct = uParamStruct
End Function
Private Function GetAppInstance() As Long
GetAppInstance = GetWindowLong _
(FindWindow("XLMAIN", Application.Caption), GWL_HINSTANCE)
End Function
Private Sub Hook_Mouse()
If lLowLevelMouse = 0 Then
lLowLevelMouse = SetWindowsHookEx _
(WH_MOUSE_LL, AddressOf LowLevelMouseProc, GetAppInstance, 0)
End If
End Sub
Private Sub UnHook_Mouse()
If lLowLevelMouse <> 0 Then _
UnhookWindowsHookEx lLowLevelMouse: lLowLevelMouse = 0
End Sub