Neue Komponente mit Komponenten

Rund um die LCL und andere Komponenten
Antworten
Eclipticon
Beiträge: 292
Registriert: Sa 5. Feb 2011, 20:38
OS, Lazarus, FPC: Windows XP VirtualBox (FPC 2.6.4, Laz 1.2.4)
CPU-Target: 32Bit
Wohnort: Wien

Neue Komponente mit Komponenten

Beitrag von Eclipticon »

Schoenen Abend wieder mal ...

Ich moechte fuer ein Projekt eine eigene visuelle Komponente basteln, die widerum visuelle Komponenten (z.B. TButton) enthaelt. Ist es prinzipiell ein richtiges vorgehen,
  • Das von TComponent abzuleiten
  • Die Unterkomponenten dynamisch in TMyComponent.Create zu erzeugen mit TheParent := Self
  • Die Unterkomponenten in TMyComponent.Destroy wieder freizugeben
Was gibt's da noch, an das man denken sollte?

Vielen Dank!

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Neue Komponente mit Komponenten

Beitrag von Socke »

Eclipticon hat geschrieben:[*] Das von TComponent abzuleiten
[*] Die Unterkomponenten dynamisch in TMyComponent.Create zu erzeugen mit TheParent := Self
[*] Die Unterkomponenten in TMyComponent.Destroy wieder freizugeben
  • Nein, TWinControl oder TCustomControl (wenn die neue Komponente auch selbst zeichnen soll) sind besser geeignet.
    TComponent ist nur für nicht visuelle Komponenten (die werden im laufenden Programm nicht angezeigt, z.B. TTimer) geeignet.
  • Ja
  • Nicht nötig, wenn du beim Erstellen Self als Parameter übergibst.

    Code: Alles auswählen

    constructor // usw...
    var
    btn: TButton;
    begin
      inherited Create(TheOwner);
      btn := TButton.Create(Self); // sobald self freigegeben wird, wird auch btn wieder freigegeben
      btn.Parent := Self;
    Alle so erstellen Komponenten werden wieder freigegeben, wenn deine Instanz von TMyComponent freigegeben wird.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Eclipticon
Beiträge: 292
Registriert: Sa 5. Feb 2011, 20:38
OS, Lazarus, FPC: Windows XP VirtualBox (FPC 2.6.4, Laz 1.2.4)
CPU-Target: 32Bit
Wohnort: Wien

Re: Neue Komponente mit Komponenten

Beitrag von Eclipticon »

Danke :-) Ich hab es mal so versucht, die child components werden aber alle nicht angezeigt. Left und Top ist schon relativ zum Canvas des Parents, oder?

Muss ich irgendwo auf Draw- oder Resize Messages reagieren? Und wo lege ich eigentlich die Defaultwerte fuer die Properties der Komponente fest?

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Neue Komponente mit Komponenten

Beitrag von Socke »

Eclipticon hat geschrieben:Danke :-) Ich hab es mal so versucht, die child components werden aber alle nicht angezeigt. Left und Top ist schon relativ zum Canvas des Parents, oder?
Ja. Warum das nicht funktioniert, kann keiner ohne Code sagen ...
Eclipticon hat geschrieben:Muss ich irgendwo auf Draw- oder Resize Messages reagieren? Und wo lege ich eigentlich die Defaultwerte fuer die Properties der Komponente fest?
Auf Draw- und Resize musst du nur reagieren, wenn deine Komponente selbst etwas zeichnen soll, wobei du dazu die Methoden Paint() bzw. Resize() überschreibst.
Die Eigenschaften setzt du im Constructor bzw. direkt bei den Properties, wenn dies möglich ist:

Code: Alles auswählen

property MyBool: Boolean read fMyBool write SetBool default True; // funktioniert mit allen ordinalen Typen
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Eclipticon
Beiträge: 292
Registriert: Sa 5. Feb 2011, 20:38
OS, Lazarus, FPC: Windows XP VirtualBox (FPC 2.6.4, Laz 1.2.4)
CPU-Target: 32Bit
Wohnort: Wien

Re: Neue Komponente mit Komponenten

Beitrag von Eclipticon »

Wenn der Herr Code moechte, bekommt er Code:

Code: Alles auswählen

unit TwoDControl;
 
interface
 
uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Buttons;
 
type
 
  TTwoDControl = class(TCustomControl)
  private
    UpBitBtn, DownBitBtn: TBitBtn;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property Height: integer default 75; // Default height im Object Inspector = 5?!?
    property Width: integer default 75;
  end;
 
procedure Register;
 
implementation
 
procedure Register;
begin
// ...
end;
 
constructor TTwoDControl.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  UpBitBtn := TBitBtn.Create(self);
  UpBitBtn.SetBounds(10, 10, 25, 25);
  DownBitBtn := TBitBtn.Create(self);
  DownBitBtn.SetBounds(35, 35, 25, 25);
end;
 
end.
Ich bin neugierig, was ich hier falsch mache ...

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Neue Komponente mit Komponenten

Beitrag von pluto »

Du musst auch noch die Parent Eigenschaft von den beiden Buttons setzten, die du hinzufügst. Die musst du einfach nur auf self setzten. Self ist ein interner Zeiger auf die Klasse selbst. In einigen Fällen wie z.b. in deinem ist er praktisch.
MFG
Michael Springwald

Eclipticon
Beiträge: 292
Registriert: Sa 5. Feb 2011, 20:38
OS, Lazarus, FPC: Windows XP VirtualBox (FPC 2.6.4, Laz 1.2.4)
CPU-Target: 32Bit
Wohnort: Wien

Re: Neue Komponente mit Komponenten

Beitrag von Eclipticon »

Hi Michael,
pluto hat geschrieben:Du musst auch noch die Parent Eigenschaft von den beiden Buttons setzten, die du hinzufügst. Die musst du einfach nur auf self setzten. Self ist ein interner Zeiger auf die Klasse selbst. In einigen Fällen wie z.b. in deinem ist er praktisch.
tu' ich das nicht mit TBitBtn.Create(self); ?

DiBo33
Beiträge: 334
Registriert: Do 11. Okt 2007, 18:01

Re: Neue Komponente mit Komponenten

Beitrag von DiBo33 »

tu' ich das nicht mit TBitBtn.Create(self); ?
(J)Nein, damit definierst du den Owner des Controls dieser muss nicht zwangsläufig gleich dem Parent sein.

Also einfach self als Parent der Controls hinzufügen (das passiert aber fast jeden bei der Entw. visueller Komponenten).

Dets
Beiträge: 61
Registriert: Di 11. Sep 2007, 16:59
OS, Lazarus, FPC: Ubuntu Maverick (L 0.9.28.2-10, FPC 2.4.0)
CPU-Target: 32Bit
Wohnort: Lage
Kontaktdaten:

Re: Neue Komponente mit Komponenten

Beitrag von Dets »

Eclipticon hat geschrieben:tu' ich das nicht mit TBitBtn.Create(self); ?
Nein. Im Konstruktor gibt man den Owner des Objekts an, also das Objekt, das sich um das spätere Freigeben kümmert. Der Parent hingegen definiert, in welchem Kontext sich das Objekt zeichnet.

Dets ...

Eclipticon
Beiträge: 292
Registriert: Sa 5. Feb 2011, 20:38
OS, Lazarus, FPC: Windows XP VirtualBox (FPC 2.6.4, Laz 1.2.4)
CPU-Target: 32Bit
Wohnort: Wien

Re: Neue Komponente mit Komponenten

Beitrag von Eclipticon »

Danke, Dibo33 und Dets, so funktionierts :-)

Jetzt versuche ich gerade, die Unterkomponenten mit meiner neuen Komponente zu resizen ... wo haenge ich mich da ein? Ins OnResize des Parents?

DiBo33
Beiträge: 334
Registriert: Do 11. Okt 2007, 18:01

Re: Neue Komponente mit Komponenten

Beitrag von DiBo33 »

Nicht unbedingt, kommt darauf an was du vorhast.

Möglw. genügt es auch die Anchors entspr. einzustellen.

Eclipticon
Beiträge: 292
Registriert: Sa 5. Feb 2011, 20:38
OS, Lazarus, FPC: Windows XP VirtualBox (FPC 2.6.4, Laz 1.2.4)
CPU-Target: 32Bit
Wohnort: Wien

Re: Neue Komponente mit Komponenten

Beitrag von Eclipticon »

Ja, koennt sich auch ueber Anchors loesen lassen, aber Code waere in diesem Fall einfacher...

OnResize?
Resize?
DoOnResize?? :shock:

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Neue Komponente mit Komponenten

Beitrag von Socke »

Eclipticon hat geschrieben:Ja, koennt sich auch ueber Anchors loesen lassen, aber Code waere in diesem Fall einfacher...
Ganz wie du willst. Sobald das etwas komplexer wird (z.B. horizontal zentriert zu einem anderen Controls), möchte ich die LCL aber wieder empfehlen.
Eclipticon hat geschrieben:OnResize?
Resize?
DoOnResize?? :shock:
So aus dem Bauch:
  • OnResize ist ein Event, in das ausgelöst wird, wenn deine Komponente die Größe ändert. Kann vom Benutzer immer geändert werden und ist auch nur für ihn vorgesehen.
  • Resize ist richtig, einfach überschreiben.
  • DoOnResize ruft OnResize auf, musst du nicht weiter beachten
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Neue Komponente mit Komponenten

Beitrag von pluto »

Resize ist richtig, einfach überschreiben.
Resize ist eine Methode die von TCustomControl bereit gestellt wird und wie schon gesagt einfach überschrieben werden kann. Aber Vorsicht: Sie wird auch aufgerufen, wenn Die Komponente keine Größe hat z.b. Breite 0 und Höhe 0. In meinem Fall musste ich das abfangen um Fehler zu vermeiden. Sie wird leider auch zwei mal aufgerufen, wenn du über die Größe über die Entsprechenden Eigenschaften Setzt.
MFG
Michael Springwald

Antworten