Wahre Höhe eines Controls bestimmen

Rund um die LCL und andere Komponenten
Antworten
LazProgger
Beiträge: 63
Registriert: Di 11. Mär 2014, 00:33

Wahre Höhe eines Controls bestimmen

Beitrag von LazProgger »

Im OnCreate erstelle ich einige Controls (Labels, Buttons, Checkboxen) dynamisch. Um die Controls anzuornden, muss ich deren Höhe wissen, die ja je nach System und Theme eine andere sein kann. Dazu benutze ich die .Height Property der Controls.

Das merkwürdige: Im OnCreate haben die Controls andere Höhen als zur Laufzeit. Ein Label kommt bei mir zum Beispiel im OnCreate auf eine Höhe von 17, zur Laufzeit hat es dann eine Höhe von 15.

Ich habe den Code testweise einmal aus dem OnCreate ins OnShow verschoben. Hier lassen sich tatsächlich die richtigen Höhen ermitteln, allerdings nur für die sichtbaren Controls. Problematisch wird dies zum Beispiel bei einem TabSheet: Die Controls auf dem sichtbaren Tab haben die "richtigen" Höhen, die auf den nicht geöffneten Tab haben die "alten" Höhen, wie sie auch im OnCreate auslesbar sind.

Um die Controls vernünftig anzuordnen bräuchte ich natürlich einheitliche Höhen und zwar die, die auch später im GUI zu sehen sind. Gibts eine Möglichkeit die zu ermitteln?

Mein Testsystem ist übrigens Windows 7, unter Linux sieht es aber auch nicht anders aus.

PS: Bitte keine Tipps zu Alternativlösungen wie Anchoring, Alignment etc, in meinem Fall geht es wirklich um die Bestimmung der wahren Höhen.

Vielen Dank für eure Tipps!

Benutzeravatar
theo
Beiträge: 11325
Registriert: Mo 11. Sep 2006, 19:01

Re: Wahre Höhe eines Controls bestimmen

Beitrag von theo »


LazProgger
Beiträge: 63
Registriert: Di 11. Mär 2014, 00:33

Re: Wahre Höhe eines Controls bestimmen

Beitrag von LazProgger »

theo hat geschrieben:So schon probiert? http://wiki.freepascal.org/Theme_library
Es geht ja nicht darum eine neue Theme zu implementieren, die Theme soll immer die des Betriebssystems sein, auf dem das Programm gerade läuft.

Das einzige Problem ist, wie ich an die Höhe eines Controls komme um es dann entsprechend anzuordnen. Mit den Controls selber bin ich zufrieden bzw der Meinung dass man hier ruhig die Standard-Controls nehmen kann damit das Programm zum jeweiligen OS Design passt.

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1782
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Wahre Höhe eines Controls bestimmen

Beitrag von corpsman »

wie wärs wenn du "onShow" nimmst. Das nehme ich immer gern, wenn graphische sachen anstehen.

Code: Alles auswählen

 
TForm.OnCreate()
begin
  allowreoder := true;
end;
 
TForm.onSHow();
begin
if allowreoder then begin
allowreoder := false;
// Hier Plazierungen durchführen
end;
end;
 
--
Just try it

LazProgger
Beiträge: 63
Registriert: Di 11. Mär 2014, 00:33

Re: Wahre Höhe eines Controls bestimmen

Beitrag von LazProgger »

corpsman hat geschrieben:wie wärs wenn du "onShow" nimmst. Das nehme ich immer gern, wenn graphische sachen anstehen.
Das hatte ich ja schon in meine Frage geschrieben, dass es im OnShow funktioniert, aber eben nicht für alles. Zum Beispiel für die nicht sichtbaren TabSheets vom PageControl geht diese Lösung nicht.

Ein Workaround wäre hier den Code jedes mal im OnChange des PageControls neu durchzuführen, aber lieber wäre mir hier eine elegantere Lösung..

Gibt es nicht irgendeine Möglichkeit die Höhen schon vorher zu ermitteln bevor sie gezeichnet sind?

Michl
Beiträge: 2513
Registriert: Di 19. Jun 2012, 12:54

Re: Wahre Höhe eines Controls bestimmen

Beitrag von Michl »

MMn benötigst Du dafür die Rückmeldung vom System in Abhängigkeit vom jeweiligen Widgetset.

D.h., Du hast mMn folgende Möglichkeiten:
LazProgger hat geschrieben:- jedes mal im OnChange des PageControls neu durchzuführen
LazProgger hat geschrieben:- ins OnShow verschoben. Hier lassen sich tatsächlich die richtigen Höhen ermitteln, allerdings nur für die sichtbaren Controls
LazProgger hat geschrieben:- Anchoring, Alignment
- Du definierst selber Fixe Höhen / Breiten für Deine Controls unabhängig vom Widgetset
- oder machst sowas in der Art ("initialisiere" alle Controls per erstem sichtbarem Tabsheet):

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
begin
  CheckBox1:=TCheckBox.Create(Self);
  CheckBox2:=TCheckBox.Create(Self);
  CheckBox1.Parent:=TabSheet1;
  CheckBox2.Parent:=TabSheet1;
end;
 
procedure TForm1.FormShow(Sender: TObject);
begin
  CheckBox2.Parent:=TabSheet2;
end; 
K.A. was für Dich die beste Lösung darstellt, ich nutze oft Anchoring, manchmal Alignment, selten fest definierte Bounds noch seltener (eigentlich nur bei Inplace-Editoren) berechne ich die Größe selber.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Antworten