How to determine the absolute location of a control (Views: 710)
Problem/Question/Abstract: Is there a built-in method for getting the absolute location of a control or do I need to step through the hierarchy? E.g.: Form1...Group1...Button1 means that the absolute left of Button1 is Form1.Left+Group1.Left+Button1.Left Answer: Solve 1: You need to use the ClientToScreen and ScreenToClient methods, like this: procedure TForm1.Button1Click(Sender: TObject); var P: TPoint; begin P := Point(Button1.Left, Button1.Top); {Button1's coordinates are expressed relative to it's parent. Using Parent.ClientToScreen converts these client coordinates to screen coordinates, which are absolute, not relative.} P := Button1.Parent.ClientToScreen(P); {Using ScreenToClient here is the same as Self.ScreenToClient. Since Self is the current instance of TForm1, this statement converts the absolute screen coordinates back to coordinates relative to Self.} P := ScreenToClient(P); ShowMessage(Format('x: %d, y: %d', [P.X, P.Y])); end; Because this code uses the absolute screen coordinates in the conversion process, it will work regardless of how deeply nested the Button is. It could be on the form, on a group on the form, on a panel in a group on the form... it doesn't matter. The code will always return the same results, the coordinates expressed in the form's client system. Solve 2: I don't know if there is a simpler method, but this one works: function GetScreenCoordinates(AControl: TControl): TPoint; begin if AControl.Parent <> nil then begin Result := AControl.Parent.ClientToScreen(Point(AContol.Left, AControl.Top)); end else begin Result := Point(AContol.Left, AControl.Top); end; end; The trick is: If a control has no parent, (Left, Top) should be the screen coordinates already (TForm). If it has a parent, the ClientToScreen function of the parent can be used to get it. Solve 3: Use TComponent.DesignInfo, which holds the Left and Top of the component. You can do this: X := LongRec(MyComponent.DesignInfo).Lo; Y := LongRec(MyComponent.DesignInfo).Hi; |