Recent

Author Topic: Getting coordinates of a control to the form (not the screen/parent)  (Read 1547 times)

Gald

  • Full Member
  • ***
  • Posts: 107
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;
Lazarus 2.0.12 r64642 FPC 3.2.0 x86_64-win64-win32/win64/Manjaro KDE 21
AMD Ryzen 3 1300X Quad-Core Processor 3.50 GHz / 8,00 GB RAM / GTX 1500 TI / 2TB M.2 NVMe

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: Getting coordinates of a control to the form (not the screen/parent)
« Reply #1 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.

Gald

  • Full Member
  • ***
  • Posts: 107
Re: Getting coordinates of a control to the form (not the screen/parent)
« Reply #2 on: April 22, 2021, 07:14:28 am »
Thank you so much!
Lazarus 2.0.12 r64642 FPC 3.2.0 x86_64-win64-win32/win64/Manjaro KDE 21
AMD Ryzen 3 1300X Quad-Core Processor 3.50 GHz / 8,00 GB RAM / GTX 1500 TI / 2TB M.2 NVMe

circular

  • Hero Member
  • *****
  • Posts: 4195
    • Personal webpage
Re: Getting coordinates of a control to the form (not the screen/parent)
« Reply #3 on: April 22, 2021, 09:05:32 am »
You can do that recursively if it can be in any number of controls.
Conscience is the debugger of the mind

alpine

  • Hero Member
  • *****
  • Posts: 1038
Re: Getting coordinates of a control to the form (not the screen/parent)
« Reply #4 on: April 22, 2021, 11:21:53 pm »
What about:
Code: Pascal  [Select][+][-]
  1. Form.ScreenToClient(Control.ClientToScreen(Control.BoundsRect.TopLeft));
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: Getting coordinates of a control to the form (not the screen/parent)
« Reply #5 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)));
« Last Edit: April 23, 2021, 01:44:29 am by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

alpine

  • Hero Member
  • *****
  • Posts: 1038
Re: Getting coordinates of a control to the form (not the screen/parent)
« Reply #6 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 (=_=)
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

 

TinyPortal © 2005-2018