Lazarus

Programming => LCL => Topic started by: Gald on April 13, 2021, 12:37:22 pm

Title: [SOLVED] A way to click through controls?
Post by: Gald on April 13, 2021, 12:37:22 pm
Hi all!

There's a way to click through controls and ignoring the OnMouseMove events?

Especially on TLabel, TShape and TImage.
Title: Re: A way to click through controls?
Post by: speter on April 13, 2021, 12:41:40 pm
I find my (left) fist works really well for this (though monitors _are_ expensive).

If this isn't helpful, maybe you should explain a bit more....

cheers
S. :)
Title: Re: A way to click through controls?
Post by: Gustavo 'Gus' Carreno on April 13, 2021, 12:44:37 pm
Hey Gald,

There's a way to click through controls and ignoring the OnMouseMove events?

Errrmm, click or click and drag?

Cuz like @SPeter said, you're not making a lot of sense here, sorry.

Cheers,
Gus
Title: Re: A way to click through controls?
Post by: Gald on April 13, 2021, 01:02:31 pm
Errrmm, click or click and drag?

>add a panel
>put some events on OnMouseOver, OnMouseLeave and OnClick
>add some labels inside this panel
>run
>events don't work when the label is behind the mouse
Title: Re: A way to click through controls?
Post by: Gustavo 'Gus' Carreno on April 13, 2021, 01:13:43 pm
Hey Gald,

>events don't work when the label is behind the mouse

They don't work on the Panel, or on the Label?
Cuz when you enter the Label, it's TLabel.OnMouseEnter that is triggered.
TPanel.OnMouseEnter is only triggered when you enter the TPanel.

Am I making sense?

Did I not understand what you're saying, again?
If so, really sorry, and can you be more specific, or include a small projects that mimics the behaviour you're describing, please?
Hopefully we can get unstuck, right?

Cheers,
Gus
Title: Re: A way to click through controls?
Post by: trev on April 13, 2021, 01:16:10 pm
The obvious answer would appear to be to use the same events (and the same event handler code) for the labels as well.
Title: Re: A way to click through controls?
Post by: Gustavo 'Gus' Carreno on April 13, 2021, 01:31:08 pm
Hey Trev,

The obvious answer would appear to be to use the same events (and the same event handler code) for the labels as well.

That's and excellent idea, why didn't I thought of that?!!??! Lack of sleep, I guess...

@Gald: I'm attaching a test project where you can see on a TMemo all the individual event firing.
Hope that helps to understand.

Cheers,
Gus
Title: Re: A way to click through controls?
Post by: Gustavo 'Gus' Carreno on April 13, 2021, 01:39:12 pm
Hey Gald,

Here's the same project but implemented like @Trev suggested: One procedure for all OnMouseEnter and another for all OnMouseLeave

It's v2 of the other project.

Cheers,
Gus
Title: Re: A way to click through controls?
Post by: Gald on April 13, 2021, 01:43:07 pm
It is the same question of this guy, but his problem was not really solved:
https://forum.lazarus.freepascal.org/index.php?topic=42177.0

include a small projects that mimics the behaviour you're describing, please?

Ok, it's done!
Title: Re: A way to click through controls?
Post by: Gustavo 'Gus' Carreno on April 13, 2021, 02:01:58 pm
Hey Gald,

Here, I fixed it, I think...

Cheers,
Gus
Title: Re: A way to click through controls?
Post by: Gustavo 'Gus' Carreno on April 13, 2021, 02:04:36 pm
Hey Gald,

Completely forgot to mention that I created my test projects with Lazarus 2.1.0, so you won't be able to compile it with 2.0.12 or below.
Sorry, forgot to create the project in 2.0.12.

I'll run the fix lpi tool WP gave me and repost the projects, sorry...

EDIT: I'm attaching the versions that are compatible with 2.0.12 and below!

Cheers,
Gus
Title: Re: A way to click through controls?
Post by: Gald on April 13, 2021, 02:14:01 pm
Here, I fixed it, I think...

Thank you, but it will not work.
The problem goes here:

  if Sender is TPanel then
    TPanel(Sender).Color := clred
  else
    Panel1.Color := clred;


I don't know the component name (panelONE) because they will be created in runtime.

Unless if there is some way to get the parent's name.
Then will be something like:

For i:=0 to ComponentCountInsideHisParent -1 do
begin
  Components.OnMouseMove := Components.Owner.OnMouseMove;
  Components.OnClick := Components.Owner.OnClick;
end;
Title: Re: A way to click through controls?
Post by: Gustavo 'Gus' Carreno on April 13, 2021, 02:27:26 pm
Hey Gald,

That's one way to do it, the other is to do it when you CREATE the components(And please use code blocks for you code here):
Code: Pascal  [Select][+][-]
  1. panel:= TPanel.Create(Self);
  2. myPanel.OnMouseMouseMove:= @ComponentMouseMove;
  3. myLabel:= TLabel.Create(panel);
  4. myLabel.Parent:= myPanel;
  5. myLabel.OnMouseMove:= @ComponentMouseMove;

Solve the problem at the BEGINNING, not after you have all the components created!

Does that make sense?

But why this prevailing idea to create UI at run-time. It baffles me to no end!!

Cheers,
Gus
Title: Re: A way to click through controls?
Post by: Gald on April 13, 2021, 03:03:02 pm
Sadly, they aren't working as expected when clicking on the label, probably because I'm moving some objects based on Panel's position.
I'll think about a better solution.

Many thanks!

But why this prevailing idea to create UI at run-time. It baffles me to no end!!

I'm trying to make a modern "Main Menu" component.
Title: Re: A way to click through controls?
Post by: Handoko on April 13, 2021, 03:39:30 pm
I modified you source code, just a workaround, not really fixes the issue. It should work as what you want but so far only for MouseMove and MouseLeave events. This should give you the basic idea if you need to improve it to check more events.

I only quickly tested on Linux GTK2. For your information OnMouseLeave has 'unfixed' issue on GTK2. You can search my old posts if you want to learn more.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, ExtCtrls, StdCtrls, Types;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     ApplicationProperties1: TApplicationProperties;
  16.     Label1: TLabel;
  17.     Label2: TLabel;
  18.     Label3: TLabel;
  19.     Label4: TLabel;
  20.     Label5: TLabel;
  21.     Panel1: TPanel;
  22.     Panel2: TPanel;
  23.     procedure ApplicationProperties1UserInput(Sender: TObject; Msg: Cardinal);
  24.     procedure FormCreate(Sender: TObject);
  25.     procedure Panel1MouseLeave(Sender: TObject);
  26.     procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer
  27.       );
  28.   end;
  29.  
  30. var
  31.   Form1: TForm1;
  32.  
  33. implementation
  34.  
  35. {$R *.lfm}
  36.  
  37. { TForm1 }
  38.  
  39. procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
  40.   Y: Integer);
  41. begin
  42.   if not(Sender is TWinControl) then Exit;
  43.   (Sender as TWinControl).Color := clred;
  44. end;
  45.  
  46. procedure TForm1.Panel1MouseLeave(Sender: TObject);
  47. begin
  48.   if not(Sender is TWinControl) then Exit;
  49.   (Sender as TWinControl).Color := clblue;
  50. end;
  51.  
  52. procedure TForm1.FormCreate(Sender: TObject);
  53. begin
  54.   Panel1.OnMouseMove  := nil;
  55.   Panel1.OnMouseLeave := nil;
  56. end;
  57.  
  58. procedure TForm1.ApplicationProperties1UserInput(Sender: TObject; Msg: Cardinal
  59.   );
  60. const
  61.   AlreadyLeave: Boolean = True;
  62. var
  63.   MousePos:   TPoint;
  64.   TestObject: TPanel;
  65. begin
  66.  
  67.   TestObject := Panel1;
  68.  
  69.   MousePos := ScreenToClient(Mouse.CursorPos);
  70.   if PtInRect(TestObject.BoundsRect, MousePos) then
  71.   begin
  72.     Panel1MouseMove(TestObject, [], MousePos.X - Panel1.Left, MousePos.Y - Panel1.Top);
  73.     AlreadyLeave := False;
  74.   end
  75.   else
  76.     if not(AlreadyLeave) then
  77.     begin
  78.       Panel1MouseLeave(TestObject);
  79.       AlreadyLeave := True;
  80.     end;
  81.  
  82. end;
  83.  
  84. end.

Title: Re: A way to click through controls?
Post by: Gald on April 14, 2021, 04:45:40 am
I only quickly tested on Linux GTK2.

Working on Windows 10 too!

Thank you all, guys!  :)
TinyPortal © 2005-2018