Position eines Controls an andere Form weitergeben

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
RuhrPotto
Beiträge: 39
Registriert: Mi 6. Mai 2015, 12:52

Position eines Controls an andere Form weitergeben

Beitrag von RuhrPotto »

Hai!

Ich möchte die Position eines Controls in einer Form an eine andere Form weitergeben um diese analog eines Popups anzeigen zu können.
Solange die Positionsermittlung (Top,Left) innerhalb der aufrufenden Form erfolgt funktioniert auch die Anzeige des aufzurufenden Form.

Übergebe ich stattdessen das Control an eine Unit (Wrapper) bekomme ich falsche Koordinaten des Controls. Die Anzeige des Forms ist immer nach unten rechts verschoben.

Folgendes OnClick für beliebige Controls funktioniert, da in der Form defeniert:

Code: Alles auswählen

 
procedure TForm1.ControlClick(Sender: TObject);
var
  p :tPoint;
begin
  p := ClientToScreen(Point((Sender as TControl).Left,(Sender as TControl).Top));
 
  TLWH.Top   := P.y;
  TLWH.Left  := P.x;
  TLWH.Width := (Sender as TControl).Width;
  TLWH.Height:= (Sender as TControl).HelpContext;
 
  FrmMyHelp.Show;
end;   
 


Übergebe ich stattdessen das Control an den Wrapper bekomme ich falsche Koordinaten

Code: Alles auswählen

 
procedure TForm1.ControlClickDirekt(Sender: TObject);
begin
  ShowMyForm((Sender as TControl));   
end;   
 
//Wrapper in UNIT
procedure ShowMyForm(myCont: TControl);
var
  CP  : TPoint;
  mP  : string;
begin
   //mP := myCont.Parent.Name;
   CP := myCont.ClientToScreen(Point(myCont.Left,myCont.Top));
   TLWH.Top   := CP.y;
   TLWH.Left  := CP.x;
   TLWH.Width := myCont.Width;
   TLWH.Height:= myCont.HelpContext;
 
   FrmMyHelp.Show;
end;   
 


Die Angaben zu Width und Height (umgewandelt) werden überigens korrekt ausgewertet! ControlToScreen liefert auch kein anderes Resultat,
Wo hab ich denn diesmal meinen Denkfehler :cry:
Jeder macht Fehler - viele Fehler brauchen EDV!

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Position eines Controls an andere Form weitergeben

Beitrag von wp_xyz »

Die Koordinaten Left,Top eines Controls sind immer relativ zum Parent, das ist das Container-Objekt, in das das Control gesetzt worden ist. Also kein ClientToScreen etc, das braucht man, um globale Bildschirmkoordinaten zu erhalten:

Code: Alles auswählen

//Wrapper in UNIT
procedure ShowMyForm(myCont: TControl);
begin
   TLWH.Top   := myCont.Top;
   TLWH.Left  := myCont.Left;
   TLWH.Width := myCont.Width;
//   TLWH.Height:= myCont.HelpContext;   // ???  Was hat die Höhe mit HelpContext zu tun?
 
  // oder kürzer: TLWH.BoundsRect := myCont.BoundsRect;
 
   FrmMyHelp.Show;
end;

RuhrPotto
Beiträge: 39
Registriert: Mi 6. Mai 2015, 12:52

Re: Position eines Controls an andere Form weitergeben

Beitrag von RuhrPotto »

Danke für die schnelle Rückmeldung und den Lösungsansatz.

Funktioniert aber leider nicht bzw. nur eingeschränkt, wenn das aufrufende Form maximiert ist. Im letzteren Fall entsprechen die TOP/LEFT-Angaben ungefähr der Position des Controls.
DIe Form, die verwendet wird hat eine Größe von 800x600 und kann auch recht unten am Bildschirm stehen. In diesem Fall wird das aufrufende Form recht oben am Bildschirm angezeigt und eben nicht am Control.
Ich benötige daher wohl doch die globalen Bildschirmkoordinaten.
Und genau letztere scheinen im Wrapper nicht mehr korrekt ermittet werden zu können.

Code: Alles auswählen

Ein Button hat Top 208 Left 204 auf der Form
ClientToScreen der aufrufenden Form liefert Top  814 Left  529   <<< stimmt
ClientToScreen im Wrapper liefert Top  737 Left 1018    <<< falsche Angabe der Position


Ich habe den (hoffentlich falschen) Eindruck, dass der Wrapper nicht korrekt die Position eines Controls berechnen kann obwohl der Parent (Form1) bekannt ist.
Jeder macht Fehler - viele Fehler brauchen EDV!

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Position eines Controls an andere Form weitergeben

Beitrag von wp_xyz »

RuhrPotto hat geschrieben:Funktioniert aber leider nicht bzw. nur eingeschränkt, wenn das aufrufende Form maximiert ist.

Da die Position eines Controls üblicherweise an der linken oberen Ecke des Formulars verankert ist (es sei denn, du hast seine Anchors verändert), sollte es keine Rolle spielen, ob das Formular maximiert ist oder nicht.

Aber wahrscheinlich verstehe ich nicht, was du eigentlich erreichen willst, denn deine Beschreibung ist schon etwas kryptisch. Am besten, du dampfst dein Projekt soweit ein, dass nur der nötige Code enthalten ist, um dem das gewünschte Verhalten zu demonstrieren, und lädst die pas, lfm, lpi und lpr-Dateien, in ein zip gepackt, hier hoch. Und wenn du einen Fehler oder ein gewünsches Programmverhalten beschreibst, stelle dir immer die Frage: Würde ich das Geschriebene verstehen, wenn ich von der ganzen Sache keine Ahnung hätte?

RuhrPotto
Beiträge: 39
Registriert: Mi 6. Mai 2015, 12:52

Re: Position eines Controls an andere Form weitergeben

Beitrag von RuhrPotto »

Die Form soll mit Informationen zum aufrufenden Control neben diesem angezeigt werden.
Wird mit Programm - siehe Anhang - vielleicht klarer ..
Dateianhänge
TestObject.zip
(360.25 KiB) 104-mal heruntergeladen
Jeder macht Fehler - viele Fehler brauchen EDV!

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Position eines Controls an andere Form weitergeben

Beitrag von wp_xyz »

In FrmMain.Button1Click wird das Rechteck TLHW relativ zum Bildschrim ermittelt: P := ClientToScreen(Point((Sender as TControl).Left,(Sender as TControl).Top)); - richtig.

In ShowMyInfo, einer Prozedur, die nichts kennt als die übergebenen Parameter, hast du CP := myCont.ClientToScreen(Point(myCont.Left,myCont.Top)). MyCont ist der geklickte Button. MyCont.ClientToScreen soll den Punkt auf absolute Bildschirmkoordianten umrechnen. Aber: vorne steht MyCont, d.h. alle Koordinaten sind vom Button aus gesehen. Im Koordinatensystem des Buttons hat die linke obere Ecke die Koordinaten 0,0. Verwendest du CP := myCont.ClientToScreen(Point(0, 0)), dann funktioniert alles richtig.

Oder, wenn Left/Top weiterverwendet werden sollen, dann geht das auch, aber man muss berücksichtigen, dass Left/Top vom Parent des Buttons aus gezählt werden. Also muss der Parent des Buttons die Funktion ClientToScreen aufrufen: CP: myCont.Parent.ClientToScreen(Point(myCont.Left, myCont.Top)) funktioniert auch.

Code: Alles auswählen

procedure ShowMyInfo(myCont: TControl);
var
  CP : TPoint;
begin
//  CP := myCont.ClientToScreen(Point(myCont.Left,myCont.Top));        // falsch
  CP := myCont.Parent.ClientToScreen(Point(myCont.Left,myCont.Top));   // richtig
//  CP := myCont.ClientToScreen(point(0, 0));                          // richtig
  TLWH.Top   := CP.y;
  TLWH.Left  := CP.x;
  TLWH.Width := myCont.Width;
  TLWH.Height:= myCont.HelpContext;
 
  FrmInfo.Show;
end;

RuhrPotto
Beiträge: 39
Registriert: Mi 6. Mai 2015, 12:52

Re: Position eines Controls an andere Form weitergeben

Beitrag von RuhrPotto »

Danke für die Unterstützung! :D
Jetzt funktioniert es.
Hatte wohl einen krassen Denkfehler und unterstellt, dass der Parent automatisch mit ausgewertet wird.
Jeder macht Fehler - viele Fehler brauchen EDV!

Antworten