Lazarus

Free Pascal => Beginners => Topic started by: Gald on April 22, 2021, 06:51:17 am

Title: Getting coordinates of a control to the form (not the screen/parent)
Post by: Gald on April 22, 2021, 06:51:17 am
Hi!
How can I get the position of some control related to the form?

Remember that using .top and .left will return the position of his parent, not the form.

Is there something like these functions below?

function  ScreenToClient(const APoint: TPoint): TPoint;
function  ClientToScreen(const APoint: TPoint): TPoint;
function  ScreenToControl(const APoint: TPoint): TPoint;
function  ControlToScreen(const APoint: TPoint): TPoint;
Title: Re: Getting coordinates of a control to the form (not the screen/parent)
Post by: Handoko on April 22, 2021, 07:03:38 am
This code works on my test:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   aPoint: TPoint;
  4. begin
  5.   aPoint := Button1.BoundsRect.TopLeft;
  6.   aPoint.Offset(Button1.Parent.Left, Button1.Parent.Top);
  7.   ShowMessage(aPoint.X.ToString);
  8. end;

Note:
Button1 is inside a TPanel.
Title: Re: Getting coordinates of a control to the form (not the screen/parent)
Post by: Gald on April 22, 2021, 07:14:28 am
Thank you so much!
Title: Re: Getting coordinates of a control to the form (not the screen/parent)
Post by: circular on April 22, 2021, 09:05:32 am
You can do that recursively if it can be in any number of controls.
Title: Re: Getting coordinates of a control to the form (not the screen/parent)
Post by: y.ivanov on April 22, 2021, 11:21:53 pm
What about:
Code: Pascal  [Select][+][-]
  1. Form.ScreenToClient(Control.ClientToScreen(Control.BoundsRect.TopLeft));
Title: Re: Getting coordinates of a control to the form (not the screen/parent)
Post by: Remy Lebeau on April 23, 2021, 01:39:00 am
What about:
Code: Pascal  [Select][+][-]
  1. Form.ScreenToClient(Control.ClientToScreen(Control.BoundsRect.TopLeft));

This is how I would do it, too.

However, Control.BoundsRect.TopLeft is the control's position within its Parent's client area.  The coordinates provided to ClientToScreen() need to be within the client area of the control that it is being called on.

So, to use BoundsRect, you would need to call ClientToScreen() on the Parent instead:

Code: Pascal  [Select][+][-]
  1. Form.ScreenToClient(Control.Parent.ClientToScreen(Control.BoundsRect.TopLeft));

Otherwise, use the control's ClientRect instead when calling ClientToScreen() on the control itself:

Code: Pascal  [Select][+][-]
  1. Form.ScreenToClient(Control.ClientToScreen(Control.ClientRect.TopLeft));

Or simpler:

Code: Pascal  [Select][+][-]
  1. Form.ScreenToClient(Control.ClientToScreen(Point(0,0)));
Title: Re: Getting coordinates of a control to the form (not the screen/parent)
Post by: y.ivanov on April 23, 2021, 02:19:26 am

However, Control.BoundsRect.TopLeft is the control's position within its Parent's client area.  The coordinates provided to ClientToScreen() need to be within the client area of the control that it is being called on.

So, to use BoundsRect, you would need to call ClientToScreen() on the Parent instead:

Code: Pascal  [Select][+][-]
  1. Form.ScreenToClient(Control.Parent.ClientToScreen(Control.BoundsRect.TopLeft));

Absolutely right! My mistake, probably due to the lack of sleep (=_=)
TinyPortal © 2005-2018