Jaafar Tribak

Well-known Member
Joined
Dec 5, 2002
Messages
9,797
Office Version
  1. 2016
Platform
  1. Windows
Hi dear forum,

In the past few months, I have posted various codes which show how to run code upon wheelmouse-scrolling.

Basically, intercepting the mouse scroll event relies on four known techniques : Subclassing, Installing a windows Mouse Hook, using the SetWinEventHook API or using the PeekMessage\GetMessage API functions.

Unfortunately, each of these methods carry their own set of issues. Namely the following isues:

1- Subclassing a window within excel is prone to crashing and only works when applied to modal userforms.

2- Installing a Mouse hook or using the SetWinEventHook API is a better alternative but, it puts a noticeable burden on excel and most importantly, it will crash the entire application (GPF) if an unhandled error occurs or if the VBE is reset before uninstalling the mouse hook.

3- PeekMessage\GetMessage is probably the safest method as it won't crash excel but, it requires continiously running a loop in the background. Obviously, this makes this method less than ideal and should probably only be used in small temporary loops during code execution.

The above mentioned issues could be avoided if the code was running from within a dll loaded into excel but, I am looking at making this work purely with straight VBA without any dependencies.

Here, I present a workaround which seems to work just fine after running various tests (XL 2007,2010,2016 32bit and 64bit).

Basically, I am installing a low level windows mouse hook but, from a second hidden excel instance created on the fly.

By running the mouse hook from a remote process, there will be no risk of crashing excel should an error occur while the hook is installed... There are no heavy loops continiously running in the background either.

The hidden excel instance communicates with the current excel session back and forth and closes itself automatically when the current excel session is closed.

I have made the code into an addin so it can be flexibly used from all open workbooks .


WheelScroll.xla


MouseWheel Event Handler singnature:
VBA Code:
Private Sub OnMouseWheelScroll( _
    ByVal WheelDirection As Long, _
    ByVal Ctrl As Integer, _
    ByVal Shift As Integer, _
    ByRef Cancel As Boolean)

WheelDirection >0 Wheel Forward
WheelDirection <0 Wheel Backward

Ctrl =0 Ctrl Key is up while mousescrolling
Ctrl =-1 Ctrl Key is down while mousescrolling

Shift =0 Shift Key is up while mousescrolling
Shift =-1 Shift Key is down while mousescrolling

Cancel =TRUE to cancel mousescrolling

Note: The above event handler must be placed in the ThisWorkbook Module of the client workbook(s) (See next post in this thread for some usage examples)



Addin Code

1
- Code in a Standard Module of the Addin:

VBA Code:
Option Explicit

Private Type POINTAPI
    X As Long
    Y As Long
End Type

Private Type MOUSEHOOKSTRUCT
    Location As POINTAPI
    MouseData As Long
    Flags As Long
    time As Long
    ExtraInfo As Long
End Type
    
    
#If VBA7 Then
    Private Declare PtrSafe Function SetTimer Lib "user32" (ByVal hwnd As LongPtr, ByVal nIDEvent As LongPtr, ByVal uElapse As Long, ByVal lpTimerFunc As LongPtr) As LongPtr
    Private Declare PtrSafe Function KillTimer Lib "user32" (ByVal hwnd As LongPtr, ByVal nIDEvent As LongPtr) As Long
    Private Declare PtrSafe Function CLSIDFromString Lib "Ole32" (ByVal lpsz As LongPtr, pclsid As Any) As Long
    Private Declare PtrSafe Function GetActiveObject Lib "OleAut32" (rclsid As Any, ByVal pvReserved As LongPtr, ppunk As Any) As Long
    Private Declare PtrSafe Function RegisterActiveObject Lib "OleAut32" (ByVal pUnk As IUnknown, rclsid As Any, ByVal dwFlags As Long, pdwRegister As Long) As Long
    Private Declare PtrSafe Function SetProp Lib "user32" Alias "SetPropA" (ByVal hwnd As LongPtr, ByVal lpString As String, ByVal hData As LongPtr) As Long
    Private Declare PtrSafe Function GetProp Lib "user32" Alias "GetPropA" (ByVal hwnd As LongPtr, ByVal lpString As String) As LongPtr
    Private Declare PtrSafe Function RemoveProp Lib "user32" Alias "RemovePropA" (ByVal hwnd As LongPtr, ByVal lpString As String) As LongPtr
    Private Declare PtrSafe Function GetDesktopWindow Lib "user32" () As LongPtr
    Private Declare PtrSafe Function CoDisconnectObject Lib "ole32.dll" (ByVal pUnk As IUnknown, pvReserved As Long) As Long
    Private Declare PtrSafe Function RevokeActiveObject Lib "oleaut32.dll" (ByVal dwRegister As Long, ByVal pvReserved As Long) As Long
    Private Declare PtrSafe Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As LongPtr, ByVal hmod As LongPtr, ByVal dwThreadId As Long) As LongPtr
    Private Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As LongPtr) As Long
    Private Declare PtrSafe Function CallNextHookEx Lib "user32" (ByVal hHook As LongPtr, ByVal ncode As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
    Private Declare PtrSafe Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As LongPtr
    Private Declare PtrSafe Function GetForegroundWindow Lib "user32" () As LongPtr
    Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
    Private Declare PtrSafe Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
    Private Declare PtrSafe Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As LongPtr)
    Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Private Declare PtrSafe Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As LongPtr, lpdwProcessId As Long) As Long
    Private Declare PtrSafe Function GetCurrentProcessId Lib "kernel32" () As Long
    
    Private lMouseHook As LongPtr
#Else
    Private Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
    Private Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
    Private Declare Function CLSIDFromString Lib "Ole32" (ByVal lpsz As Long, pclsid As Any) As Long
    Private Declare Function GetActiveObject Lib "OleAut32" (rclsid As Any, ByVal pvReserved As Long, ppunk As Any) As Long
    Private Declare Function RegisterActiveObject Lib "OleAut32" (ByVal pUnk As IUnknown, rclsid As Any, ByVal dwFlags As Long, pdwRegister As Long) As Long
    Private Declare Function SetProp Lib "user32" Alias "SetPropA" (ByVal hwnd As Long, ByVal lpString As String, ByVal hData As Long) As Long
    Private Declare Function GetProp Lib "user32" Alias "GetPropA" (ByVal hwnd As Long, ByVal lpString As String) As Long
    Private Declare Function RemoveProp Lib "user32" Alias "RemovePropA" (ByVal hwnd As Long, ByVal lpString As String) As Long
    Private Declare Function GetDesktopWindow Lib "user32" () As Long
    Private Declare Function CoDisconnectObject Lib "ole32.dll" (ByVal pUnk As IUnknown, pvReserved As Long) As Long
    Private Declare Function RevokeActiveObject Lib "oleaut32.dll" (ByVal dwRegister As Long, ByVal pvReserved 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 UnhookWindowsHookEx Lib "user32" (ByVal hHook 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 GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
    Private Declare Function GetForegroundWindow Lib "user32" () As Long
    Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
    Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
    Private Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
    Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
    
    Private lMouseHook As Long
#End If

Private bHookIsSet As Boolean
Private bCancelArgument As Boolean
Private lErr As Long
Private oAddin As Workbook
Private oActiveWb As Object
Private lWheelDirection As Long
Private iCtrlKey As Integer
Private iShiftKey As Integer


Public Sub StartMouseWheelHook()
    
    Dim ClassID(0 To 3) As Long
    Dim lOleId As Long
    Dim lRet As Long
    Dim oApp As Application

    On Error GoTo Xit
    
    If ThisWorkbook.ReadOnly Then Exit Sub
    
    If CBool(GetProp(GetDesktopWindow, "OleId")) Then Exit Sub
    
    Call SetProp(GetDesktopWindow, "PID", GetCurrentProcessId)

    lRet = CLSIDFromString(StrPtr("{88D97E8B-D351-4FF4-A8EB-BF18EDD35267}"), ClassID(0))
    lRet = RegisterActiveObject(ThisWorkbook, ClassID(0), 0, lOleId)
    
    If lRet = 0& Then
        Call SetProp(GetDesktopWindow, "OleId", lOleId)
        Set oApp = New Application
        With oApp
            .Workbooks.Open Filename:=ThisWorkbook.FullName, UpdateLinks:=False, ReadOnly:=True
            .Run "On_Open"
        End With
    End If
    
    Exit Sub
Xit:
    oApp.Quit
    Call ResetProps
    Call FinishMouseWheelHook

End Sub

Public Sub FinishMouseWheelHook()

    Dim pUnk As IUnknown
    Dim Wb As Workbook
    Dim ClassID(0 To 3) As Long
    Dim lRet As Long
    
    On Error GoTo Xit
    
    If ThisWorkbook.ReadOnly Then Exit Sub
    
    lRet = CoDisconnectObject(ThisWorkbook, 0)
    lRet = RevokeActiveObject(CLng(GetProp(GetDesktopWindow, "OleId")), 0)
    lRet = CLSIDFromString(StrPtr("{88D97E8B-D351-4FF4-A8EB-BF18EDD35268}"), ClassID(0))
    lRet = GetActiveObject(ClassID(0), 0, pUnk)
    
    If lRet = 0& Then
        Set Wb = pUnk
        Set pUnk = Nothing
        If Not Wb Is Nothing Then
            Wb.Parent.Run "On_Close"
            Set Wb = Nothing
        End If
        Call RemoveProp(GetDesktopWindow, "OleId")
    End If
    
    Exit Sub
Xit:
    Call ResetProps

End Sub

Public Sub Register(ByVal Wb As Workbook)

    Dim ClassID(0 To 3) As Long
    Dim lOleId As Long
    Dim lRet As Long
    
    If Wb.IsAddin = False Then
        lRet = RevokeActiveObject(CLng(GetProp(GetDesktopWindow, "CurrentWorkbook")), 0)
        lRet = CLSIDFromString(StrPtr("{88D97E8B-D351-4FF4-A8EB-BF18EDD35271}"), ClassID(0))
        lRet = RegisterActiveObject(Wb, ClassID(0), 0, lOleId)
        
        If lRet = 0& Then
            Call SetProp(GetDesktopWindow, "CurrentWorkbook", lOleId)
        End If
    End If

End Sub



'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
'             All of the following routines are executed ONLY in the second excel instance !!!
'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Private Sub On_Open()

    Dim ClassID(0 To 3) As Long
    Dim lOleId As Long
    Dim lRet As Long

    If ThisWorkbook.ReadOnly Then
        Set oAddin = GetAddin
        If oAddin Is Nothing Then
            ThisWorkbook.Saved = True: Application.Quit
        Else
            lRet = CLSIDFromString(StrPtr("{88D97E8B-D351-4FF4-A8EB-BF18EDD35268}"), ClassID(0))
            lRet = RegisterActiveObject(ThisWorkbook, ClassID(0), 0, lOleId)
            If lRet = 0& Then
                Call SetTimer(Application.hwnd, 0, 0, AddressOf CallSetHook)
            End If
        End If
    End If

End Sub

Private Sub On_Close()

    Call UnInstallMouseHook
    Call KillTimer(Application.hwnd, 0)
    Call ResetProps
    Set oAddin = Nothing
    ThisWorkbook.Saved = True
    DoEvents
    Application.OnTime Now, "CloseRemoteXL"

End Sub

Private Sub ResetProps()
    Call RemoveProp(GetDesktopWindow, "OleId")
    Call RemoveProp(GetDesktopWindow, "PID")
    Call RemoveProp(GetDesktopWindow, "CurrentWorkbook")
End Sub

Private Sub CloseRemoteXL()
    Application.Quit
End Sub

Private Sub CallSetHook()

    If Not bHookIsSet Then
        InstallMouseHook
    End If
    Call KillTimer(Application.hwnd, 0)

End Sub

Private Sub InstallMouseHook()

    Const WH_MOUSE_LL As Long = 14

    If Not bHookIsSet Then
        lMouseHook = SetWindowsHookEx(WH_MOUSE_LL, AddressOf MouseProc, GetModuleHandle(vbNullString), 0&)
        bHookIsSet = lMouseHook <> 0
    End If

End Sub

Private Sub UnInstallMouseHook()

    If bHookIsSet Then
        Call UnhookWindowsHookEx(lMouseHook)
        bHookIsSet = lMouseHook = 0
    End If

End Sub

#If Win64 Then
    Private Function MouseProc(ByVal ncode As Long, ByVal wParam As LongLong, ByRef lParam As MOUSEHOOKSTRUCT) As LongLong
#Else
    Private Function MouseProc(ByVal ncode As Long, ByVal wParam As Long, ByRef lParam As MOUSEHOOKSTRUCT) As Long
#End If

    Const HC_ACTION As Long = 0&
    Const WM_MOUSEWHEEL = &H20A
    Const VK_SHIFT = &H10
    Const VK_CONTROL = &H11
    
    Dim sBuff As String * 256, lRet As Long
    Dim lProcessId As Long

    On Error Resume Next
    
    If GetAddin Is Nothing Then
        Call On_Close
        Exit Function
    End If
    
    If ncode < HC_ACTION Then
        MouseProc = CallNextHookEx(lMouseHook, ncode, wParam, lParam)
        Exit Function
    End If

    lRet = GetClassName(GetForegroundWindow, sBuff, 256)
    If Left(sBuff, lRet) = "wndclass_desked_gsk" Then Exit Function
    
    Call GetWindowThreadProcessId(GetForegroundWindow, lProcessId)
    If GetProp(GetDesktopWindow, "PID") <> lProcessId Then Exit Function
    
    iCtrlKey = 0: iShiftKey = 0
    If wParam = WM_MOUSEWHEEL Then
        If GetKeyState(VK_CONTROL) And &H80 Then
            iCtrlKey = -1
        End If
        If GetKeyState(VK_SHIFT) And &H80 Then
            iShiftKey = -1
        End If
        lWheelDirection = Hiword(CLng(lParam.MouseData))
        Call KillTimer(Application.hwnd, 0)
        Call SetTimer(Application.hwnd, 0, 0&, AddressOf CallOnScroll)
        MouseProc = -1
        Exit Function
    End If
    
    MouseProc = CallNextHookEx(lMouseHook, ncode, wParam, ByVal lParam)

End Function

Private Sub CallOnScroll()
    
    Call KillTimer(Application.hwnd, 0)
    
    On Error Resume Next

    Set oActiveWb = GetActiveWorkBook
    
    With oActiveWb.Application
        bCancelArgument = False
        lErr = 0
        Call .Run(oActiveWb.CodeName & ".OnMouseWheelScroll", lWheelDirection, iCtrlKey, iShiftKey, bCancelArgument)
        lErr = Err.Number
        Call Sleep(50)
        Call SetTimer(Application.hwnd, 0, 0&, AddressOf DoWheelScroll)
    End With

End Sub

Private Sub DoWheelScroll()

    Const MOUSEEVENTF_WHEEL = &H800
    Const WHEEL_DELTA = 120

    Call KillTimer(Application.hwnd, 0)
    
    On Error Resume Next

    Call UnInstallMouseHook
        With oActiveWb.Application
            If .hwnd = GetForegroundWindow Then
                If bCancelArgument = False Or lErr Then
                    lErr = 0
                    Call mouse_event(MOUSEEVENTF_WHEEL, 0&, 0&, lWheelDirection, 0)
                End If
            End If
        End With
    Call InstallMouseHook

End Sub

Private Function GetAddin() As Workbook

    Dim pUnk As IUnknown
    Dim ClassID(0 To 3) As Long
    Dim lRet As Long

    lRet = CLSIDFromString(StrPtr("{88D97E8B-D351-4FF4-A8EB-BF18EDD35267}"), ClassID(0))
    lRet = GetActiveObject(ClassID(0), 0, pUnk)
    If lRet = 0& Then Set GetAddin = pUnk

End Function

Private Function GetActiveWorkBook() As Object

    Dim pUnk As IUnknown
    Dim ClassID(0 To 3) As Long
    Dim lRet As Long

    On Error Resume Next

    lRet = CLSIDFromString(StrPtr("{88D97E8B-D351-4FF4-A8EB-BF18EDD35271}"), ClassID(0))
    lRet = GetActiveObject(ClassID(0), 0, pUnk)
    If lRet = 0& Then Set GetActiveWorkBook = pUnk

End Function

Private Function Hiword(ByVal DWord As Long) As Integer
    Hiword = (DWord And &HFFFF0000) \ &H10000
End Function


2- Code in the ThisWorkbook Module of the Addin:

VBA Code:
Option Explicit

Private WithEvents XlApp As Application

Private Sub Workbook_Open()
    Set XlApp = Application
    Call StartMouseWheelHook
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Call FinishMouseWheelHook
End Sub

Private Sub Workbook_AddinInstall()
    Call Register(ActiveWorkbook)
End Sub

Private Sub XlApp_NewWorkbook(ByVal Wb As Workbook)
    Call Register(Wb)
End Sub

Private Sub XlApp_WorkbookActivate(ByVal Wb As Workbook)
    Call Register(Wb)
End Sub

In the next post, I'll show some interesting uses of the addin.
 
Furthermore another question. I share the application, I am working on, with another person. The add-in is now saved in a windows add-in folder. Else I had to reload it everytime after leaving the application. How do you do this in a more isolated way. I would prefer to add it in a subfolder of my application and deliver it with the package to others. Is this possible what is your experience/solution? Thanks in advance



1617875517232.png
 
Upvote 0

Excel Facts

Which came first: VisiCalc or Lotus 1-2-3?
Dan Bricklin and Bob Frankston debuted VisiCalc in 1979 as a Visible Calculator. Lotus 1-2-3 debuted in the early 1980's, from Mitch Kapor.
I have integrated the code into my application and have some observations that yuou may explain from your knowledge of the add-in.
1. A scroll bar in a form scrolls down but not up. So one direction works
2. If I scroll in a combobox, the combobox is left and does scroll down or up the list as your demo shows.
Thanks in advance for your help.
Rob
 
Upvote 0
Furthermore another question. I share the application, I am working on, with another person. The add-in is now saved in a windows add-in folder. Else I had to reload it everytime after leaving the application. How do you do this in a more isolated way. I would prefer to add it in a subfolder of my application and deliver it with the package to others. Is this possible what is your experience/solution? Thanks in advance



View attachment 36188

There shouldn't be a problem placing the addin file in your client workbook path.

After you have placed the addin in the client workbook folder, you can install the addin automatically via code upon opening the client workbook :

Add this to the Client ThisWorkbook Module:
VBA Code:
Private Sub Workbook_Open()

    Dim AddinPathName As String, AddinName As String
    
    AddinPathName = ThisWorkbook.Path & Application.PathSeparator & "WheelScroll.xla"
    AddinName = Mid(AddinPathName, InStrRev(AddinPathName, Application.PathSeparator) + 1, Len(AddinPathName))
    AddinName = Left(AddinName, InStrRev(AddinName, ".") - 1)

    If Len(Dir(AddinPathName)) Then
        If Application.AddIns(AddinName).Installed = False Then
            If InstallAddin(AddinPathName, True) Then
                MsgBox "Addin: " & "'WheelScroll.xla'" & " Installed", , "Success"
            Else
                MsgBox "Failed to Install '" & AddinPathName & "'", , "ERROR"
            End If
        End If
    Else
        MsgBox "Wrong File PathName!" & vbNewLine & AddinPathName
    End If

End Sub


Private Function InstallAddin(ByVal AddinPathName As String, ByVal bInstall As Boolean) As Boolean

    Dim AddinName As String
    
    Application.AddIns.Add(AddinPathName).Installed = bInstall
    AddinName = Mid(AddinPathName, InStrRev(AddinPathName, Application.PathSeparator) + 1, Len(AddinPathName))
    AddinName = Left(AddinName, InStrRev(AddinName, ".") - 1)
    InstallAddin = Application.AddIns(AddinName).Installed

End Function

Now, each time the client workbook is open, it will automatically check if the addin is installed... If it is not installed, the code will install it.
 
Upvote 0
I have integrated the code into my application and have some observations that yuou may explain from your knowledge of the add-in.
1. A scroll bar in a form scrolls down but not up. So one direction works
2. If I scroll in a combobox, the combobox is left and does scroll down or up the list as your demo shows.
Thanks in advance for your help.
Rob
1- Do you mean a Scrollbar control placed on the userform or the actual userform scrollbar like the one showing on the gif image ?
2- Sorry, I don't understand what you mean.. If you can rephrase that .
 
Upvote 0
I have an Combobox on my form in a frame. When I select the list by the dropdown button selection the list appears and when I scroll the list is closed and focus moves to other control on form.
The strange thing is that your demo application works perfect. I checked the cpmbobox properties but there are no differences. I tried the differences but these did not make any difference. The form is modal, but yours also. So I am puzzled?
By the way I appreciate the time you spend to help me. If I ask too much, just say no.
Thanks
 
Upvote 0
Hello Jaafar
I have several forms in my application and in another form the combobox exactly behaves as in your demo.
I really do not know how to solve this because the code you provided is Microsoft Windows related and I do have no clue about that.

Maybe I can share my application with you but not in this group. So if you would like to find out why this code does not work in some of my cases you could look into my app?
Or iof you can give me spome clue's sio that I can try to find out myself is also welcome.
Regards
Rob
 
Upvote 0
Hello Jaafar

I did found something that explains what happens: In some comboboxes I set listrows to 0 which means that it will create as many lines as entries are available. In that case there is no scrollbar and thgus the mousewheel does not scroll through the list but in stead end the list and moves mouse to next tab in the form.

But I stil have an issue with a scrollbar control in a form. Thta scrolls down with the mousewheel but not up. So there seems to be an issue with the code you have made I think. Does your code count with a scrollbar control in a form?

Thanks

Rob
 
Upvote 0
Hello Jaafar

I did found something that explains what happens: In some comboboxes I set listrows to 0 which means that it will create as many lines as entries are available. In that case there is no scrollbar and thgus the mousewheel does not scroll through the list but in stead end the list and moves mouse to next tab in the form.

But I stil have an issue with a scrollbar control in a form. Thta scrolls down with the mousewheel but not up. So there seems to be an issue with the code you have made I think. Does your code count with a scrollbar control in a form?

Thanks

Rob
Hello Jaafar

I got also scrollbar working. I deleted it and replaced it by a new one and nowamzingly it works.
So thanks a lot for al your help.
Rob
 
Upvote 0
First off, thank you Jaafar for this magnificent work! I do believe it is exactly what I'm needing; but I do have a couple of questions: What do you mean when referring to the second instance of excel? Is this the workbook with the user form? Once the mouse-hook is functional, how does one capture screen coordinates for mouse-click events? Thank you.
 
Upvote 0
Addin usage example 1: ifound it is working only on userfom,not work on worksheet,win10 、office365 64bit
 
Upvote 0

Forum statistics

Threads
1,223,903
Messages
6,175,284
Members
452,630
Latest member
OdubiYouth

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top