"MousePreview" monitoring mouse clicks? lazarus / 31-LCL ---------------------------------------------------------------------- ArminLinder · 2017-02-22 09:36 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);begin  EditStatus.Text := 'Cleared by keypress';end; procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;  Shift: TShiftState; X, Y: Integer);begin  EditStatus.Text := 'Cleared by mouse click';end;  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. ---------------------------------------------------------------------- balazsszekely · 2017-02-22 09:49 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. ---------------------------------------------------------------------- ArminLinder · 2017-02-22 10:09 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. ---------------------------------------------------------------------- balazsszekely · 2017-02-22 10:41 QuoteSolution #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. ---------------------------------------------------------------------- ArminLinder · 2017-02-22 11:37 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. ---------------------------------------------------------------------- balazsszekely · 2017-02-22 12:23 @Nimral QuoteI 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. ---------------------------------------------------------------------- Sergei · 2017-11-17 12:14 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses  ..., Forms, LMessages; procedure TForm1.FormCreate(Sender: TObject);begin  Application.AddOnUserInputHandler(@MouseHook);end; procedure TForm1.FormDestroy(Sender: TObject);begin  // To prevent possible system resource leaks  Application.RemoveOnUserInputHandler(@MouseHook);end; procedure TForm1.MouseHook(Sender: TObject; Msg: Cardinal);begin   if (Msg <> LM_MOUSEMOVE) and (Msg <> LM_NCMOUSEMOVE) then Exit;   // Do stuffend; ---------------------------------------------------------------------- 741 · 2025-08-01 20:37 I just tried this technique and I get "Error variable identifier expected" as follows TfrmMain = class(TForm)    ... procedure MouseHook(Sender: TObject; Msg: Cardinal);    ... end;     procedure TfrmMain.FormCreate(Sender: TObject); begin ...    Application.AddOnUserInputHandler(@MouseHook); //Error Variable Identifier expected ... end; ---------------------------------------------------------------------- Remy Lebeau · 2025-08-01 21:34 Quote from: 741 on August 01, 2025, 10:37:40 pmCode: [Select]Application.AddOnUserInputHandler(@MouseHook); //Error Variable Identifier expected Did you make sure there is not another identifier named MouseHook in scope somewhere?  Try using a more unique name, like MyMouseHook or DoMouseHook.  Or, try qualifying the method: @Self.MouseHook. ---------------------------------------------------------------------- 741 · 2025-08-02 09:59 Hi Thanks for the input. This still fails (with the same error) - here is a simple test case. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i    TTest = class      procedure MouseHook_SJB(Sender: TObject; Msg: Cardinal);    procedure TestHook;   end; ......procedure TTest.TestHook;begin  Application.AddOnUserInputHandler(@Self.MouseHook_SJB);end;  Also, I notice that omitting the @ allows compilation Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TfrmMain.FormCreate(Sender: TObject);var   strIniFileFullName: string;begin   Application.AddOnUserInputHandler(@Self.MouseHook1);  //ERROR   Application.AddOnUserInputHandler(MouseHook1);        //NO Error   Application.AddOnUserInputHandler(@MouseHook1);       //Error  I am trying to recall - Is the procedure name itself a pointer? UPDATE: Omitting the @ seems to make it work. ---------------------------------------------------------------------- dseligo · 2025-08-02 10:44 Quote from: 741 on August 02, 2025, 11:59:16 amCode: [Select]   Application.AddOnUserInputHandler(@Self.MouseHook1);  //ERROR    Application.AddOnUserInputHandler(MouseHook1);        //NO Error I am trying to recall - Is the procedure name itself a pointer? UPDATE: Omitting the @ seems to make it work. You use mode Delphi. If you use mode Delphi than you omit @, otherwise (in mode ObjFPC) you put @. See here (number 2): https://www.freepascal.org/daily/doc/prog/progse76.html And here (number 1): https://www.freepascal.org/daily/doc/prog/progse74.html ---------------------------------------------------------------------- 741 · 2025-08-02 19:31 Thank you!