Recent

Author Topic: "MousePreview" monitoring mouse clicks?  (Read 4699 times)

Nimral

  • Full Member
  • ***
  • Posts: 111
  • Keep it simple.
"MousePreview" monitoring mouse clicks?
« on: February 22, 2017, 10:36:58 am »
Hi,

on a form I wish to clear the status line when either any button or key is pressed anywhere, or a mouse click occurs.

For keys, this was not difficult: set KeyPreview to true, and in the FormKeyUp handler do the job.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
  2. begin
  3.   EditStatus.Text := 'Cleared by keypress';
  4. end;
  5.  
  6. procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  7.   Shift: TShiftState; X, Y: Integer);
  8. begin
  9.   EditStatus.Text := 'Cleared by mouse click';
  10. end;
  11.  

As you can see, I tried the same with OnMouseUp, but had no good results, the event does not fire, if the mouse is over any visible control, e.g. a button or even a panel, which is almost always the case.

Is there an alternative to defining an OnMouseUp handler into each and every control, something like a "MousePreview" like there is a "KeyPreview"?

Thnx

Armin.
« Last Edit: February 22, 2017, 10:57:52 am by Nimral »
Lazarus 2.0.8 on Windows, Raspberry Pi OS, VMWare Workstation

GetMem

  • Hero Member
  • *****
  • Posts: 3782
Re: "MousePreview" monitoring mouse clicks?
« Reply #1 on: February 22, 2017, 10:49:06 am »
Hi Nimral,

You're under windows, just create a mouse hook and you're good to go. If you find the hook a difficult solution, with a timer watch the mouse position(Mouse.CursorPos) translate to your form(ScreenToClient) then calculate which component is below the mouse. The third solution is to redirect every MouseUp to a single event at least for those component you're interested in. The second and third solution are cross-platform.

Nimral

  • Full Member
  • ***
  • Posts: 111
  • Keep it simple.
Re: "MousePreview" monitoring mouse clicks?
« Reply #2 on: February 22, 2017, 11:09:40 am »
Thanks, GetMem,

from what I see here ...

http://stackoverflow.com/questions/25482429/hooking-the-mouse-and-keyboard-in-lazarus

creating a mouse hook doesn't seem to be too much of work, but it ruins the platform-independentness I have right now.

Solution #2: haven't tried this yet, but as far as your suggestion goes, I'd be able to track the mouse position, OK, but how would I detect a mouse click then? I don't see how this approach could help me.

Solution #3: that's exactly what I'd like to avoid, having to overwrite each and every control's OnMouseUp.

Let's see if someone else has an additional approach, if not, I'll implement #1.

Thanks,

Armin.
Lazarus 2.0.8 on Windows, Raspberry Pi OS, VMWare Workstation

GetMem

  • Hero Member
  • *****
  • Posts: 3782
Re: "MousePreview" monitoring mouse clicks?
« Reply #3 on: February 22, 2017, 11:41:27 am »
Quote
Solution #3: that's exactly what I'd like to avoid, having to overwrite each and every control's OnMouseUp.
I'm not sure what do you mean by overwrite here? OnFormCreate, with a recursively function, loop through form controls and assign a common OnMouseUp to each control you're interested in. This can be done selectively(only for buttons for example, or for a mixed type of controls tagged with a unique Tag). When OnMouseUp is fired just check the sender(tag, name) and take the appropriate action. I don't know what exactly are you trying to achieve but it shouldn't be to difficult with the above method.

Nimral

  • Full Member
  • ***
  • Posts: 111
  • Keep it simple.
Re: "MousePreview" monitoring mouse clicks?
« Reply #4 on: February 22, 2017, 12:37:51 pm »
I see your point.

You still overwrite each and every control's OnMouseUp, but you don't do it by hand, which is kind of a progress.

Problem I see: this move is quite unexpected for anyone modifying my code in the future, including me in a year's time or so :-) So if someone decides to define his own MouseUp event for any control, my routine would silently reverse his definition on FormCreate.

I still don't like the approach, though you showed me some kind of automating it :-)

No bad words, just a matter of taste :-)

Greetz, Armin.
Lazarus 2.0.8 on Windows, Raspberry Pi OS, VMWare Workstation

GetMem

  • Hero Member
  • *****
  • Posts: 3782
Re: "MousePreview" monitoring mouse clicks?
« Reply #5 on: February 22, 2017, 01:23:49 pm »
@Nimral

Quote
I still don't like the approach, though you showed me some kind of automating it :-)
You can make it fully automated. I mean if somebody creates a MouseDown event from the designer, you can redirect to this event after it was catched on the generic event.

Ok. I'm not gonna insist further.  :)
« Last Edit: February 22, 2017, 01:32:36 pm by GetMem »

Sergei

  • New member
  • *
  • Posts: 8
Re: "MousePreview" monitoring mouse clicks?
« Reply #6 on: November 17, 2017, 01:14:20 pm »
Another possible solution is here: http://forum.lazarus-ide.org/index.php?topic=16843.0

It registers a global hook for user events and seems cross-platform (I'm on Win 64).

Code: Pascal  [Select][+][-]
  1. uses
  2.   ..., Forms, LMessages;
  3.  
  4. procedure TForm1.FormCreate(Sender: TObject);
  5. begin
  6.   Application.AddOnUserInputHandler(@MouseHook);
  7. end;
  8.  
  9. procedure TForm1.FormDestroy(Sender: TObject);
  10. begin
  11.   // To prevent possible system resource leaks
  12.   Application.RemoveOnUserInputHandler(@MouseHook);
  13. end;
  14.  
  15. procedure TForm1.MouseHook(Sender: TObject; Msg: Cardinal);
  16. begin
  17.    if (Msg <> LM_MOUSEMOVE) and (Msg <> LM_NCMOUSEMOVE) then Exit;
  18.  
  19.   // Do stuff
  20. end;
  21.  
« Last Edit: November 17, 2017, 03:10:34 pm by Sergei »

 

TinyPortal © 2005-2018