Recent

Author Topic: How to capture horizontal mouse scroll event?  (Read 19504 times)

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: How to capture horizontal mouse scroll event?
« Reply #15 on: December 11, 2018, 02:53:14 am »
Many thanks jamie. I had given this some thought, but did not figure out a solution. That could work. I wonder which is fired first, if it is predictable then perhaps one could just wait for the second event.
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: How to capture horizontal mouse scroll event?
« Reply #16 on: December 11, 2018, 03:02:40 am »
I guess one could keep track of either one, and wait for the other before acting. I wonder though if a scroll of 0 is sent as an event.
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: How to capture horizontal mouse scroll event?
« Reply #17 on: December 11, 2018, 06:20:02 pm »
I see where my confusion came from. I was trying to respond to MouseWheel events in a TPaintBox. It has OnMouseWheel, but not  OnMouseWheelHorz. A TForm has both, apparently this is as of 2.0.0:

http://wiki.freepascal.org/Lazarus_2.0.0_release_notes

Awesome!
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: How to capture horizontal mouse scroll event?
« Reply #18 on: December 11, 2018, 07:06:52 pm »
Here is my solution to avoid multiple redraws during mouse wheel scrolling of an image:

Code: Pascal  [Select][+][-]
  1. { TVBitmapView.DoMouseWheel
  2.   Call for OnMouseWheel and OnMouseWheelHorz events. For OnMouseWheel set
  3.   dx = 0, for OnMouseWheelHorz set dy = 0. If wait = false then the translation
  4.   is made immediately. If wait = true a second call (event OnMouseWheel or
  5.   OnMouseWheelHorz) is required and the two offests are done at one time. }
  6. procedure TVBitmapView.DoMouseWheel(Shift: TShiftState; dx, dy: integer;
  7.   wait: boolean);
  8. begin
  9.   if fWheelWaiting then begin // second of two calls
  10.     Translate(dx + fWheelDX, dy + fWheelDY);
  11.     fWheelWaiting := false;
  12.     fWheelDX := 0;
  13.     fWheelDY := 0;
  14.   end else if wait then begin // first of two calls
  15.     fWheelWaiting := true;
  16.     fWheelDX := dx;
  17.     fWheelDY := dy;
  18.   end else begin // one call
  19.     Translate(dx, dy);
  20.     fWheelWaiting := false;
  21.     fWheelDX := 0;
  22.     fWheelDY := 0;
  23.   end;
  24. end;    

It is within a class that a use for image display in a TPaintBox.
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: How to capture horizontal mouse scroll event?
« Reply #19 on: December 11, 2018, 11:37:22 pm »
There is also another way to do this..

When ever you receive the event for either direction of mouse scroll you can do a PeekMessage and obtain the opposite
mouse scroll message if it exists.
 
 If it does exists then you can perform both scrolls in one event and remove the message from the que before it gets
sent.

  If it is not in the que then it could be assumed that only one direction was done and no need to remove any messages

The only true wisdom is knowing you know nothing

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: How to capture horizontal mouse scroll event?
« Reply #20 on: December 11, 2018, 11:55:48 pm »
There is also another way to do this..

When ever you receive the event for either direction of mouse scroll you can do a PeekMessage and obtain the opposite
mouse scroll message if it exists.
 
 If it does exists then you can perform both scrolls in one event and remove the message from the que before it gets
sent.

  If it is not in the que then it could be assumed that only one direction was done and no need to remove any messages

Thanks! That may be a more reliable method. My solution could get two of the same events, instead of one of each, before scrolling. It would still do the correct scroll, but on every other event. It should be fine if the user has a trackpad or ball, but maybe not on other devices.
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: How to capture horizontal mouse scroll event?
« Reply #21 on: December 12, 2018, 01:42:28 am »
Since it looks like you are into a smoother results of image manipulations I did something that many interest you..

I have an app where I resize the form and have an image in it on a PainBox to show, I like to maintain the image
aspect ratio to a 4:3 and there for when user sizes the form via one the sides I don't readjust the opposite using the
OnShow event or rescale within the OnPaint event of the paintbox because it causes redraws and flicker, not smooth looking
at all.

 What I do is implement the WM_Sizing Message, not WM_SIZE, this message is sent before the window actually gets
resized giving you a chance to see what the new size is going to be and also allowing you to make adjustments to the
size if they are not desirable, in most cases they are not.

 When the LCL form finally receives the SIZE message the values are those that you adjusted to and exactly where you
want them, there is no flickering this way due to repeating draws.

 Now only if we could get the LCL guys to allow that message to pass through the filter of the TFORM class, it would be nice
but for now, it is filtered out and thus you need to hook the window procedure of the form to process the message yourself
outside the TFORM class.

 For this reason, I really think they should support OnSizing along with the OnSize they have now.

 Hint Hint…
The only true wisdom is knowing you know nothing

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: How to capture horizontal mouse scroll event?
« Reply #22 on: December 13, 2018, 06:19:32 pm »
Your tips are much appreciated jamie. Regarding the mouse wheel suggestion, I'm having trouble figuring out how to use PeekMessage, and am not finding much in the way of examples. I'm trying something like this:

Code: Pascal  [Select][+][-]
  1. procedure TImageForm.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  2.   WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  3. var
  4.   msg: TMsg;
  5. begin
  6.   if PeekMessage(msg, 0, LM_MOUSEHWHEEL, LM_MOUSEHWHEEL, PM_REMOVE) then
  7.     // we have vert and then horz scrolling, deal with that here
  8.   else
  9.     // just vert
  10.   Handled := true;
  11. end;
  12.  
  13. procedure TImageForm.FormMouseWheelHorz(Sender: TObject; Shift: TShiftState;
  14.   WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  15. var
  16.   msg: TMsg;
  17. begin
  18.   if PeekMessage(msg, 0, LM_MOUSEWHEEL, LM_MOUSEWHEEL, PM_REMOVE) then
  19.     // we have horz and then vert scrolling, deal with that here
  20.   else
  21.     // just horz
  22.   Handled := true;
  23. end;

I figured one or the other PeekMessage calls would return true, but neither do. Clearly I am doing something wrong. Any tips or links would be appreciated!

Cheers,
VTwin
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: How to capture horizontal mouse scroll event?
« Reply #23 on: December 13, 2018, 11:50:07 pm »
You need to send the handle of the window

PeekMessage(msg, Handle, …….

Or what ever control has the focus..



The only true wisdom is knowing you know nothing

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: How to capture horizontal mouse scroll event?
« Reply #24 on: December 14, 2018, 01:34:35 am »
Thanks. I now have something like this:

Code: Pascal  [Select][+][-]
  1. procedure TImageForm.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  2.   WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  3. var
  4.   msg: TMsg;
  5.   hnd: THandle;
  6. begin
  7.   hnd := ImageForm.Handle;
  8.   if PeekMessage(msg, hnd, LM_MOUSEHWHEEL, LM_MOUSEHWHEEL, PM_REMOVE) then
  9.     // we have vert and then horz scrolling, deal with that here
  10.   else
  11.     // just vert
  12.   Handled := true;
  13. end;
  14.  
  15. procedure TImageForm.FormMouseWheelHorz(Sender: TObject; Shift: TShiftState;
  16.   WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  17. var
  18.   msg: TMsg;
  19.   hnd: THandle;
  20. begin
  21.   hnd := ImageForm.Handle;
  22.   if PeekMessage(msg, hnd, LM_MOUSEWHEEL, LM_MOUSEWHEEL, PM_REMOVE) then
  23.     // we have horz and then vert scrolling, deal with that here
  24.   else
  25.     // just horz
  26.   Handled := true;
  27. end;

No change. :(

Cheers,
VTwin
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: How to capture horizontal mouse scroll event?
« Reply #25 on: December 14, 2018, 03:20:51 am »
Not sure if it will work but you could try using the handle of PaintBox.Canvas or overriding PaintBox.WindowProc
« Last Edit: December 14, 2018, 03:23:21 am by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

CCRDude

  • Hero Member
  • *****
  • Posts: 596
Re: How to capture horizontal mouse scroll event?
« Reply #26 on: December 14, 2018, 10:25:38 am »
You need to send the handle of the window

PeekMessage(msg, Handle, …….

Or what ever control has the focus..

Take a look at the documentation. 0 wasn't a bad idea, the form handle neither.
Quote
PeekMessage retrieves messages associated with the window identified by the hWnd parameter or any of its children as specified by the IsChild function, and within the range of message values given by the wMsgFilterMin and wMsgFilterMax parameters. Note that an application can only use the low word in the wMsgFilterMin and wMsgFilterMax parameters; the high word is reserved for the system.

But I guess another important question would be how these events are triggered. Is the second one available immediately while still reacting to the first one? Are multiple horizontal ones triggered after multiple vertical ones, for example?

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: How to capture horizontal mouse scroll event?
« Reply #27 on: December 14, 2018, 05:03:31 pm »
Not sure if it will work but you could try using the handle of PaintBox.Canvas or overriding PaintBox.WindowProc

No dice with PaintBox.Canvas.Handle. :(
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: How to capture horizontal mouse scroll event?
« Reply #28 on: December 14, 2018, 05:10:59 pm »

Take a look at the documentation. 0 wasn't a bad idea, the form handle neither.

But I guess another important question would be how these events are triggered. Is the second one available immediately while still reacting to the first one? Are multiple horizontal ones triggered after multiple vertical ones, for example?

I saw an example with handle = 0, and figured the Form would default. Either way, no dice. Good point, perhaps calling PeekMessage within the handler will not work.

I did wonder about how many and when the events would fire: hvhvhv, vhvhvh, vvhhvvhh? I was hoping for a clean solution, ah well.
« Last Edit: December 14, 2018, 05:13:25 pm by VTwin »
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: How to capture horizontal mouse scroll event?
« Reply #29 on: December 14, 2018, 07:38:57 pm »
I guess my original solution should be ok if I can assume the events come in pairs, and the user has a trackpad or trackball, not an antique (?) mouse with a single wheel.

It would be nice though to have one event, maybe:
 
MouseWheelHorzVert(Sender: TObject; Shift: TShiftState;
  WheelDeltaX, WheelDeltaY: Integer; MousePos: TPoint; var Handled: Boolean);

Not a complaint, as I am grateful to see the new event handlers, just a thought.

It is not crucial, but gives the user some expected behavior. I was having them hold down the Shift key to scroll with the mouse, not very intuitive. Of course the scrollbars are available.

I'd appreciate any additional thoughts, especially insight into using PeekMessage, or what the sequence of MouseWheel and MouseWheelHorz messages is.

EDIT: Regarding the desire to limit the redraws, some of my users load very large high resolution images.
« Last Edit: December 14, 2018, 07:54:28 pm by VTwin »
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

 

TinyPortal © 2005-2018