Page 1 of 1
[SOLVED] Reliable #WM_MOUSEWHEEL value?
Posted: Sat Dec 06, 2025 3:50 pm
by Joubarbe
Code: Select all
OpenWindow(0, 0, 0, 720, 640, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
Procedure.i WinCallback(WindowID, Message, WParam, LParam)
Define Result = #PB_ProcessPureBasicEvents
If Message = #WM_MOUSEWHEEL
Debug -(WParam >> 16) / #WHEEL_DELTA
EndIf
ProcedureReturn Result
EndProcedure
SetWindowCallback(@WinCallback())
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
With that code, when I pull the wheel towards me, I have negative value. But I also have negative value when I push it away from me, but only when I give it a good spin! ie. if I go very slowly, it returns 0. So it's very unreliable. (I'm using a touchpad); how to recognise with 100% certainty that the mouse wheel is going up or down?
SOLVED:
Code: Select all
OpenWindow(0, 0, 0, 720, 640, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
Procedure.i WinCallback(WindowID, Message, WParam, LParam)
Define Result = #PB_ProcessPureBasicEvents
If Message = #WM_MOUSEWHEEL
Define Wheel.w = (WParam & $FFFF0000) >> 16
If Wheel < 0
Debug "Down"
ElseIf Wheel > 0
Debug "Up"
EndIf
EndIf
ProcedureReturn Result
EndProcedure
SetWindowCallback(@WinCallback())
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: Reliable #WM_MOUSEWHEEL value?
Posted: Sat Dec 06, 2025 4:38 pm
by RASHAD
Hi
You can try
Windows x64
Code: Select all
If Message = #WM_MOUSEWHEEL
value = wParam >> 24
If value = 0
Debug "up"
ElseIf value = 255
Debug "down"
EndIf
EndIf
Re: Reliable #WM_MOUSEWHEEL value?
Posted: Sat Dec 06, 2025 4:44 pm
by Joubarbe
RASHAD wrote: Sat Dec 06, 2025 4:38 pm
Hi
You can try
Windows x64
Code: Select all
If Message = #WM_MOUSEWHEEL
value = wParam >> 24
If value = 0
Debug "up"
ElseIf value = 255
Debug "down"
EndIf
EndIf
Yep, that works, thank you! I don't know anything about this topic, but there's always some low level games like Dwarf Fortress that don't like touchpads. I cannot scroll in those games without having a buggy behaviour (it always goes up when scrolling too fast).
Re: Reliable #WM_MOUSEWHEEL value?
Posted: Sat Dec 06, 2025 4:46 pm
by PureLust
You should check the Event Parameters.
Code: Select all
Debug ""
OpenWindow(0, 0, 0, 300, 200, "Test your Mousewheel inside here", #PB_Window_SystemMenu)
Procedure.i WinCallback(WindowID, Message, WParam, LParam)
Define Result = #PB_ProcessPureBasicEvents
If Message = #WM_MOUSEWHEEL
Wheel.w = (EventwParam() & $FFFF0000) >> 16
If Wheel < 0
Debug -1
ElseIf Wheel > 0
Debug 1
EndIf
EndIf
ProcedureReturn Result
EndProcedure
SetWindowCallback(@WinCallback())
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
(Used Tipp by HeXOR from
THIS Post.)
Re: Reliable #WM_MOUSEWHEEL value?
Posted: Sat Dec 06, 2025 4:54 pm
by Joubarbe
Doesn't work with me. EventwParam() is always 0. We go through a callback here, so WParam must be used. But the previous example works fine.
EDIT: Actually no, the example of RASHAD doesn't work when I go too fast. But yours work all the time, so thank you!

Re: Reliable #WM_MOUSEWHEEL value?
Posted: Sat Dec 06, 2025 5:10 pm
by PureLust
I'm not sure, if there is a real difference between WParam and EventwParam(), but there is i difference in RASHADs code and mine (or better say from HeXOR) how the Value is processed. As
HeXOR wrote in his Post, he is not a fried of fixed values, so am I.
Pls try this code, and check if it also works fine.
If so, it was just the difference in processing the value from WParam, that made the difference in reliability.
Code: Select all
Debug ""
OpenWindow(0, 0, 0, 300, 200, "Test your Mousewheel inside here", #PB_Window_SystemMenu)
Procedure.i WinCallback(WindowID, Message, WParam, LParam)
Define Result = #PB_ProcessPureBasicEvents
If Message = #WM_MOUSEWHEEL
Wheel.w = (WParam & $FFFF0000) >> 16
If Wheel < 0
Debug -1
ElseIf Wheel > 0
Debug 1
EndIf
EndIf
ProcedureReturn Result
EndProcedure
SetWindowCallback(@WinCallback())
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: Reliable #WM_MOUSEWHEEL value?
Posted: Sat Dec 06, 2025 5:29 pm
by Axolotl
The difference between wParam and EventWParam() lies in the correct call position.
EventWParam() probably only returns valid values after calling WaitWindowEvent() (WindowEvent()) and not within the callback function.
BTW:
I do this acc. to the MSDN help pages ...
Code: Select all
Procedure.w GET_WHEEL_DELTA_WPARAM(wParam) ; WORD
ProcedureReturn (wParam >> 16) & $FFFF
EndProcedure
Procedure WinCallback(hwnd, umsg, wParam, lParam)
Protected delta
Select umsg
Case #WM_MOUSEWHEEL
delta = GET_WHEEL_DELTA_WPARAM(wParam) / #WHEEL_DELTA
SetGadgetText(2, Str(delta))
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
If OpenWindow(0, 0, 0, 400, 200, "MouseWheel Event handling example...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TextGadget(0, 8, 8, 240, 20, "use the MouseWheel and watch this: ")
TextGadget(1, 8, 32, 160, 20, "MouseWheel Direction " )
TextGadget(2, 176, 32, 40, 20, "<do it>", #PB_Text_Right)
SetWindowCallback(@WinCallback(), 0)
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIf
Re: Reliable #WM_MOUSEWHEEL value?
Posted: Sat Dec 06, 2025 5:41 pm
by PureLust
Joubarbe wrote: Sat Dec 06, 2025 4:54 pm
EDIT: Actually no, the example of RASHAD doesn't work
when I go too fast. But yours work all the time, so thank you!
Usually each 'tick' from the Mousewheel is interpreted as #WHEEL_DELTA (which is set to
120 by default).
So, if RASHADs code does not work (because its assuming a fixed value), it might be, that your Touchpad gives back more 'ticks' at once (e.g. 240, 360,...)
You can check that with the following code:
Code: Select all
Debug "#WHEEL_DELTA Default-Value: "+#WHEEL_DELTA
OpenWindow(0, 0, 0, 300, 200, "Test your Mousewheel inside here", #PB_Window_SystemMenu)
Procedure.i WinCallback(WindowID, Message, WParam, LParam)
Define Result = #PB_ProcessPureBasicEvents
If Message = #WM_MOUSEWHEEL
Wheel.w = (EventwParam() & $FFFF0000) >> 16
If Wheel < 0
Debug "Value : " + Str(Wheel) + " - UP "+Str(Abs(Wheel/#WHEEL_DELTA)) + " Tick(s)"
ElseIf Wheel > 0
Debug "Value : " + Wheel + " - DOWN "+Str(Wheel/#WHEEL_DELTA) + " Tick(s)"
EndIf
EndIf
ProcedureReturn Result
EndProcedure
SetWindowCallback(@WinCallback())
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Anyway, recoling to WinAPI, HeXORs way [Value.
w = (EventwParam() & $FFFF0000) >> 16] seems to be the way to handle the Data from WParam right.
"The high-order word indicates the distance the wheel is rotated, expressed in multiples or divisions of WHEEL_DELTA, which is 120." 
Re: Reliable #WM_MOUSEWHEEL value?
Posted: Sat Dec 06, 2025 6:21 pm
by RNBW
I have tried all the alternatives and I get RASHAD's and Purelust's code to work, with the exception of his last bit of code. When I tried that I got Value -120 UP 1 Tick(s) when scrolling down and 120 DOWN 1 Tick(s) when scrolling up.
Re: Reliable #WM_MOUSEWHEEL value?
Posted: Sat Dec 06, 2025 6:28 pm
by PureLust
Axolotl wrote: Sat Dec 06, 2025 5:29 pm
BTW:
I do this acc. to the MSDN help pages ...
Oh, I see. The Problem in your first code was only, that you have not handled the Result from [x >> 16] as a Word-Value (e.g. by storing it into a Word-Variable), so you don't get a signed result.
$ffff (as a Long = 65535) is different to $ffff (as a Word = -1).
Here is your original code, only added the usage of the Word variable Wheel.
w and now it's working as expected:
Code: Select all
OpenWindow(0, 0, 0, 720, 640, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
Procedure.i WinCallback(WindowID, Message, WParam, LParam)
Define Result = #PB_ProcessPureBasicEvents
If Message = #WM_MOUSEWHEEL
Wheel.w = WParam >> 16
Debug Str((WParam >> 16) / #WHEEL_DELTA) + " - " + Str(Wheel / #WHEEL_DELTA)
EndIf
ProcedureReturn Result
EndProcedure
SetWindowCallback(@WinCallback())
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: Reliable #WM_MOUSEWHEEL value?
Posted: Sun Dec 07, 2025 12:00 am
by BarryG
I've been doing it like this for years with no problem:
Code: Select all
#mouse_wheel_up=-1
CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
#mouse_wheel_down=-545
CompilerElse
#mouse_wheel_down=1
CompilerEndIf
[...]
If ev=#WM_MOUSEWHEEL ; From WaitWindowEvent()
dir=-(EventwParam()>>16)/#WHEEL_DELTA
If dir=#mouse_wheel_up
; Do something when scrolled up
ElseIf dir=#mouse_wheel_down
; Do something when scrolled down
EndIf
EndIf
Re: Reliable #WM_MOUSEWHEEL value?
Posted: Sun Dec 07, 2025 9:16 am
by Joubarbe
BarryG wrote: Sun Dec 07, 2025 12:00 am
I've been doing it like this for years with no problem:
Code: Select all
OpenWindow(0, 0, 0, 720, 640, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
#mouse_wheel_up=-1
CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
#mouse_wheel_down=-545
CompilerElse
#mouse_wheel_down=1
CompilerEndIf
Procedure.i WinCallback(WindowID, Message, WParam, LParam)
Define Result = #PB_ProcessPureBasicEvents
If Message=#WM_MOUSEWHEEL ; From WaitWindowEvent()
Define dir=-(EventwParam()>>16)/#WHEEL_DELTA
If dir=#mouse_wheel_up
Debug "up"
; Do something when scrolled up
ElseIf dir=#mouse_wheel_down
Debug "down"
; Do something when scrolled down
EndIf
EndIf
ProcedureReturn Result
EndProcedure
SetWindowCallback(@WinCallback())
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Dwarf Fortress have been doing their system for years too, and that doesn't mean it works for everyone. Your code doesn't take into account multiple scrolling steps done at the same time. Take the code below, every step has an event, but not in your code; it basically goes one by one. It's definitely not wrong, but it's not entirely right. Plus, this arbitrary value feels very weird to me. The faster you scroll, the higher the number. And again, as it has been previously noted, WParam should be converted to a Word.
Code: Select all
If Message = #WM_MOUSEWHEEL
Define Wheel.w = (WParam & $FFFF0000) >> 16
If Wheel < 0
Debug "Down"
ElseIf Wheel > 0
Debug "Up"
EndIf
EndIf
Re: [SOLVED] Reliable #WM_MOUSEWHEEL value?
Posted: Sun Dec 07, 2025 1:31 pm
by BarryG
I meant my code is only meant to show if the wheel is scrolled up or down, so you can do something from that. That's all. Any deeper use is up to you.
In my case, it zooms in or out of an image when scrolled, and it works fine.