Option Explicit
Public bLooping As Boolean
Private Type POINTAPI: X As Long: Y As Long: End Type
#If VBA7 Then
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As LongPtr)
Private Declare PtrSafe Function PeekMessage Lib "user32" Alias "PeekMessageA" (lpMsg As Msg, ByVal hWnd As LongPtr, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long, ByVal wRemoveMsg As Long) As Long
Private Declare PtrSafe Function WaitMessage Lib "user32" () As Long
Private Declare PtrSafe Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Type Msg: hWnd As LongPtr: message As Long: wParam As LongPtr: lParam As LongPtr: time As Long: pt As POINTAPI: End Type
#If Win64 Then
Private Const NULL_PTR = 0
Private Declare PtrSafe Function AccessibleObjectFromPoint Lib "Oleacc" (ByVal arg1 As LongPtr, ppacc As IAccessible, pvarChild As Variant) As Long
#Else
Private Const NULL_PTR = 0&
Private Declare PtrSafe Function AccessibleObjectFromPoint Lib "Oleacc" (ByVal lX As Long, ByVal lY As Long, ppacc As IAccessible, pvarChild As Variant) As Long
#End If
Private Function HiWord(Param As LongPtr) As Integer
Call CopyMemory(HiWord, ByVal VarPtr(Param) + 2&, 2&)
End Function
#Else
Private Const NULL_PTR = 0&
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function PeekMessage Lib "user32" Alias "PeekMessageA" (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 GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
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 GetDpiForWindow Lib "user32" (ByVal hWnd As Long) As Long
Private Function HiWord(Param As Long) As Integer
Call CopyMemory(HiWord, ByVal VarPtr(Param) + 2&, 2&)
End Function
#End If
Sub MouseWheelOut(control As Object, Optional yy As Single = 0, Optional pilote As Object = Nothing)
Const WHEEL_DELTA = 120&, WM_MOUSEWHEEL = &H20A, PM_NOREMOVE = &H0&
Dim tMsg As Msg, lDelta As Integer, pos As POINTAPI, criter As Boolean, A
Dim PosControl As IAccessible
Do
GetCursorPos pos
#If Win64 Then
Dim lngPtr As LongPtr
CopyMemory lngPtr, pos, LenB(pos)
AccessibleObjectFromPoint lngPtr, PosControl, 0
#Else
AccessibleObjectFromPoint pos.X, pos.Y, PosControl, 0
#End If
'Debug.Print PosControl.accRole ' 33 = LIST 46 = COMBOBOX 10 = CLIENT
criter = (PosControl.accRole = 33 Or PosControl.accRole = 46)
If Not criter Then
bLooping = False
ActiveSheet.ScrollArea = "" 'debloque le scrollarea de la feuille
control.TopLeftCell.Select: 'la selection provoque le replis de la combo
Exit Sub
End If
bLooping = True
ActiveSheet.ScrollArea = control.TopLeftCell.Address 'bloque le scrollarea de la feuille a la cellule la plus proche du control( EVITE LES PETITS SURSAUTS)
Call WaitMessage
If PeekMessage(tMsg, NULL_PTR, WM_MOUSEWHEEL, WM_MOUSEWHEEL, PM_NOREMOVE) Then
lDelta = HiWord(tMsg.wParam)
If lDelta > 0& Then
On Error Resume Next
control.TopIndex = Application.Max(control.TopIndex - 1, 0)
On Error GoTo 0
Else
On Error Resume Next
control.TopIndex = Application.Min(control.TopIndex + 1, control.ListCount - 1)
On Error GoTo 0
End If
End If 'End of PeekMessage
DoEvents
Loop Until bLooping = False
End Sub