Is it possible to filter mouse wheel scroll messages?

x64 Replacement/Alternative to Microsoft's IntelliMouse application.
Forum rules
Please read the forum rules before posting for the first time.
The more information you can provide, the quicker and more accurately someone can help.
NOTE: To reduce spam, new users can not post links, files or images until they have at least 4 posts.
Post Reply
asformylasttrick
New User
Posts: 2
Joined: Sun Jul 28, 2024 7:11 pm

Is it possible to filter mouse wheel scroll messages?

Post by asformylasttrick »

XMBC Version: 2.20.5
Installed or Portable version: Portable
Windows Version: 10 x64 LTSC 21H2
Mouse Information (brand/model): A4tech RT7
How long have you used XMBC?: 3 months
What language and keyboard layout do you use in Windows?: English mostly

Good day, I have a question regarding possibility of new feature in XMBC.

Background of the problem.
Some people, me including, complain sometimes about the mouse wheel spin direction being registered as opposite for a moment. It causes short bobbing up and down motion experience of the scrolled window view. Some people complain that it happens with long time serving mice, some people claim it happens with newly bought. Other people recommend them dusting out their device. It does help to eliminate issue to some people, it doesn't to the rest, though.

I thought, maybe there could be implemented software filter for mouse scroll? I can imagine rough algorithm, but I can't code it myself.

It could work like this: catch the mouse wheel scroll direction message, get current time, and if next scroll message comes sooner than N milliseconds (adjustable by user) and declares opposite scroll direction, then block/discard it, or substitute it with scroll message of the same direction as previous and pass it further. Also, let user choose if they want to filter both directions of scroll, or only one specific.

Working with timer/clock is a common requirement with request from topic "Feature request: Clear mouse wheel buffer when leaving current window", so I don't get my hopes too high.

First of all, would its implementation be technically possible in principle?
And second, would it be inside the scope of XMBC functionality, or would require separate application, maybe more like driver?
You would need to find a faulty mouse like this for testing, I guess.

Thank you.
User avatar
phil
Site Admin
Posts: 7733
Joined: Sun Apr 06, 2003 11:12 pm

Re: Is it possible to filter mouse wheel scroll messages?

Post by phil »

I’m away on vacation at the moment so excuse the short reply from my mobile…

It might be possible without the bit that changes the reversed direction (that is also doable but it would be out of sequence ) as injecting a reversed message would go after any messages already in the buffer.

However there are some issues…

1. XMBC can not flush the mouse buffer - it has no visibility of that, it only intercepts messages in the windows mouse hook.

2. If a game is using raw input / direct input then XMBC can not block that. It only works at the mouse hook level - so I suspect this will not be close enough to the hardware lever - will require some sort of driver/filter driver and that’s not something I can do.

whilst we could try it in XMBC, it might be easier to try it outside of XMBC first to see if it will work - maybe an auto hot key macro (not sure that’s possible) or a quick standalone c++/c# test concept code - no point changing XMBC if it’s not going to be possible!
--[ Phil ]--
--[ Administrator & XMBC Author ]--
Logitech G9/G604/M720/MX518, Microsoft Intellimouse, Trust 16341 BT Mouse
Windows 10 x64, AMD Ryzen 5900x, MSI x570 Tomahawk, 32GB DDR4,
nVidia RTX 2070s, Evo 970 1Tb NVME, 2x2TB WD Black (RAID1)
asformylasttrick
New User
Posts: 2
Joined: Sun Jul 28, 2024 7:11 pm

Re: Is it possible to filter mouse wheel scroll messages?

Post by asformylasttrick »

Small update.

You said "hook", I thought "hmmm".
Then I did google a little. And I have found thread on PureBasic forum about exactly this.

*uh-oh, NOTE: To reduce spam, new users can not post links, files or images until they have at least 4 posts.
Ok then, just search the internet for "Purebasic forum [Solved] Mouse wheel hook laggy in Windows", topic number is 80336.

While I can't write programs from scratch, reading docs and modifying existing code is something I could handle if it is not too complicated.
So I have changed example provided by user mk-soft to do some testing.

Well, filtering can help to remove unwanted messages from the middle or an end of fast sequence when user spins wheel non-stop.
But it can't do anything about single misdirections which may occur when wheel was rotated by one sector. Whether it was right or wrong direction, is unpredictable.
And if misdirected message is the first one in long sequence, then filtering backfires, as all proper directions following wrong one during filtered threshold period are lost.

Conclusion:
1. It's better to get working mouse or repair faulty one.
2. PureBasic is cool.
3. XMBC does not need this function as it isn't fixing the problem.

Here is modified code if anyone is curious.

Code: Select all

Macro LOWORD(dwValue)
  (dwValue & $FFFF)
EndMacro

Macro HIWORD(dwValue)
  (dwValue >> 16)
EndMacro

Enumeration #WM_USER + 1
  #WM_USER_MOUSEWHEEL
EndEnumeration

Structure MSLLHOOKSTRUCT
  pt.point
  mouseData.l
  flags.l
  time.l
  *dwExtraInfo
EndStructure

Global MouseWheelHook,MouseWheelWindow,MouseWheelDir

;*****SETTINGS AND VARIABLES FOR FILTERING*****
Global.l msgLastTime = 0, msgCurrentTime, msgDeltaTime
Global.l msgUpThresholdTime = 256
Global.l msgDownThresholdTime = 256
Global.l filterUp = 1
Global.l filterDown = 1
Global.l lastNotSkippedwNewParam = 0
;**********************************************

Procedure LowLevelMouseProc(nCode.i,wParam.i,lParam.i)
  Protected *data.MSLLHOOKSTRUCT, wNewParam.l, lNewParam.l
  If wParam = #WM_MOUSEWHEEL
    *data = lParam
    wNewParam = *data\mouseData & $FFFF0000 
    lNewParam = (*data\pt\y << 16) | (*data\pt\x & $FFFF) 
    
    ;*****CALCULATION OF DELAY BETWEEN MESSAGES
    msgCurrentTime = *data\time
    msgDeltaTime = msgCurrentTime-msgLastTime
    msgLastTime = msgCurrentTime
    ;*****
    
    PostMessage_(MouseWheelWindow,#WM_USER_MOUSEWHEEL,wNewParam,lNewParam)    
 
    ;*****SKIPPING MESSAGES
    If msgDeltaTime < msgUpThresholdTime
      If filterUp = 1
        If (wNewParam < 0) And (lastNotSkippedwNewParam > 0)
          ProcedureReturn 1
        EndIf
      EndIf
    EndIf
    
    If msgDeltaTime < msgDownThresholdTime
      If filterDown = 1
        If (wNewParam > 0) And (lastNotSkippedwNewParam < 0)
          ProcedureReturn 1
        EndIf
      EndIf
    EndIf
    
    lastNotSkippedwNewParam = wNewParam    
    ;*****
    
  EndIf
  ProcedureReturn CallNextHookEx_(MouseWheelHook,nCode,wParam,lParam)
EndProcedure

Procedure AddMouseWheelHook(hWnd)
  If MouseWheelHook=0
    MouseWheelHook=SetWindowsHookEx_(#WH_MOUSE_LL,@LowLevelMouseProc(),GetModuleHandle_(0),0)
  EndIf
  MouseWheelWindow=hWnd
  ProcedureReturn MouseWheelHook
EndProcedure

Procedure RemoveMouseWheelHook()
  If MouseWheelHook
    UnhookWindowsHookEx_(MouseWheelHook)
    MouseWheelHook=0
  EndIf
EndProcedure

; ****

Procedure MyWindowCallback(WindowID, Message, wParam, lParam)
  Protected Result = #PB_ProcessPureBasicEvents
  Protected info.s, dwValue.l, dwValue2.l
  
  Select Message
    Case #WM_USER_MOUSEWHEEL
      dwValue = wParam
      dwValue2 = lParam
      info = "User Message Delta = " + Str(HIWORD(dwValue) / #WHEEL_DELTA) 
      info + " dt: " + msgDeltaTime + " lastwP: " + lastNotSkippedwNewParam
      Debug info
      
    Case #WM_MOUSEWHEEL
      dwValue = wParam
      dwValue2 = lParam
      info = "Window Message Delta = " + Str(HIWORD(dwValue) / #WHEEL_DELTA) 
      Debug info
      
  EndSelect
  
  ProcedureReturn Result
EndProcedure


If OpenWindow(0,400,200,640,320,"Mouse Hook",#PB_Window_SystemMenu)
  
  AddMouseWheelHook(WindowID(0))

  SetWindowCallback(@MyWindowCallback())
  
  Repeat
    ev=WaitWindowEvent()
  Until ev=#PB_Event_CloseWindow
EndIf
User avatar
phil
Site Admin
Posts: 7733
Joined: Sun Apr 06, 2003 11:12 pm

Re: Is it possible to filter mouse wheel scroll messages?

Post by phil »

Nice... well researched :)
Not important here, but if you were to develop further, I think you forgot to call RemoveMouseWheelHook() at the end of the program.
Windows will do that anyway when the process ends (hence not important in this case) but just thought I'd mention it for future reference!
--[ Phil ]--
--[ Administrator & XMBC Author ]--
Logitech G9/G604/M720/MX518, Microsoft Intellimouse, Trust 16341 BT Mouse
Windows 10 x64, AMD Ryzen 5900x, MSI x570 Tomahawk, 32GB DDR4,
nVidia RTX 2070s, Evo 970 1Tb NVME, 2x2TB WD Black (RAID1)
Post Reply