Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Eigene Komponete / Darstellungsfehler?! (https://www.delphipraxis.net/183230-eigene-komponete-darstellungsfehler.html)

FAM 22. Dez 2014 09:38

Eigene Komponete / Darstellungsfehler?!
 
Liste der Anhänge anzeigen (Anzahl: 3)
Hallo Zusammen,

also ich versuche gerade mich an der Komponenten-Entwicklung ... soweit so gut, eigentlich ;)
Mein Problem besteht in der Laufzeit...

1. FAMPanel => Komponente abgeletitet von TPanel-> OK.

Delphi-Quellcode:
unit famui;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type

  CorporateDesign = record
    white: TColor;
    black: TColor;
    gray: TColor;
    darkgray: TColor;
    blue: TColor;
    blueLight: TColor;
    red: TColor;
    font: String;
  end;

  FAMPanel = class(TPanel)
  private
    { Private-Deklarationen }
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Published-Deklarationen }
  end;

const
  _CorporateDesign: CorporateDesign = (white: clWhite; black: clBlack;
    gray: $00F8F8F8; darkgray: $00E5E5E5; blue: $00D37C00; blueLight: $00E9BE80;
    red: $001619DA; font: 'Roboto Light');

implementation

{ FAMPanel }

constructor FAMPanel.Create(AOwner: TComponent);
begin
  inherited;
  self.BevelInner := bvNone;
  self.BevelOuter := bvNone;
  self.Color := _CorporateDesign.white;
  self.font.Name := _CorporateDesign.font;
end;

destructor FAMPanel.Destroy;
begin

  inherited;
end;

end.
2. FAMCard => Komponente abgeletitet von FAMPanel -> OK.
2.1 3 panels (FAMPanel) der Komponente (FAMCard) hinzugefügt -> OK

Delphi-Quellcode:
unit card;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, famui;

type

  FAMCard = class(FAMPanel)
  private
    { Private-Deklarationen }
    Header: FAMPanel;
    Content: FAMPanel;
    Footer: FAMPanel;
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Published-Deklarationen }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('FAMUI', [FAMCard]);
end;

{ TFamGUI }

constructor FAMCard.Create(AOwner: TComponent);
begin
  inherited;

  // Default size of fam card
  self.Width := 600;
  self.Height := 400;

  // Create header of card
  Header := FAMPanel.Create(self);
  Header.Parent := self;
  Header.Color := _CorporateDesign.gray;
  Header.Align := alTop;
  Header.Height := 90;

  // Create content of card
  Content := FAMPanel.Create(self);
  Content.Parent := self;
  Content.Color := _CorporateDesign.white;
  Content.Align := alClient;

  // Create footer of card
  Footer := FAMPanel.Create(self);
  Footer.Parent := self;
  Footer.Color := _CorporateDesign.gray;
  Footer.Align := alBottom;
  Footer.Height := 90;

end;

destructor FAMCard.Destroy;
begin
  inherited;

end;

end.
3. Komponete wurde installiert -> OK
Anhang 42340

4. Komponete im Designer / neues Projekt -> OK
Anhang 42341

5. Komponete nach der Kompilierung -> Error
hier sind Header, Content, Footer nicht zu sehen.

Anhang 42342

woher kommt dieser Unterschied?

Uwe Raabe 22. Dez 2014 10:35

AW: Eigene Komponete / Darstellungsfehler?!
 
Ich kann jetzt nicht prüfen, ob das dein Problem löst, aber für solche zusammengesetzten Komponenten sollte man SetSubComponent direkt nach dem
Delphi-Quellcode:
Create
verwenden.

Delphi-Quellcode:
constructor FAMCard.Create(AOwner: TComponent);
begin
  inherited;

  // Default size of fam card
  self.Width := 600;
  self.Height := 400;

  // Create header of card
  Header := FAMPanel.Create(self);
  Header.SetSubComponent(true);
  Header.Parent := self;
  Header.Color := _CorporateDesign.gray;
  Header.Align := alTop;
  Header.Height := 90;

  // Create content of card
  Content := FAMPanel.Create(self);
  Content.SetSubComponent(true);
  Content.Parent := self;
  Content.Color := _CorporateDesign.white;
  Content.Align := alClient;

  // Create footer of card
  Footer := FAMPanel.Create(self);
  Footer.SetSubComponent(true);
  Footer.Parent := self;
  Footer.Color := _CorporateDesign.gray;
  Footer.Align := alBottom;
  Footer.Height := 90;

end;

FAM 22. Dez 2014 10:43

AW: Eigene Komponete / Darstellungsfehler?!
 
Hallo Uwe,

habe es mal gesetzt (zusätzlich auch visible := true) ... bringt beides nichts

Delphi-Quellcode:
  // Default size of fam card
  self.Width := 600;
  self.Height := 400;

  // Create header of card
  Header := FAMPanel.Create(self);
  Header.SetSubComponent(true);
  Header.Visible := true;
  Header.Parent := self;
  Header.Color := _CorporateDesign.gray;
  Header.Align := alTop;
  Header.Height := 90;

  // Create content of card
  Content := FAMPanel.Create(self);
  Content.SetSubComponent(true);
  Content.Visible := true;
  Content.Parent := self;
  Content.Color := _CorporateDesign.white;
  Content.Align := alClient;

  // Create footer of card
  Footer := FAMPanel.Create(self);
  Footer.SetSubComponent(true);
  Footer.Visible := true;
  Footer.Parent := self;
  Footer.Color := _CorporateDesign.gray;
  Footer.Align := alBottom;
  Footer.Height := 90;
andere vorschläge :)?

FAM 22. Dez 2014 11:11

AW: Eigene Komponete / Darstellungsfehler?!
 
Habe die Lösung gefunden.

Mit Hilfe von

Delphi-Quellcode:
   
property Header: FAMPanel read FHeader write SetHeader;
    property Content: FAMPanel read FContent write SetContent;
    property Footer: FAMPanel read FFooter write SetFooter;
und die entsprechende implementierung geht es.

Delphi-Quellcode:
unit card;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, famui;

type

  FAMCard = class(FAMPanel)
  private
    { Private-Deklarationen }
    FUnterKomponente: FAMPanel;
    FHeader: FAMPanel;
    FFooter: FAMPanel;
    FContent: FAMPanel;
    procedure SetContent(const Value: FAMPanel);
    procedure SetFooter(const Value: FAMPanel);
    procedure SetHeader(const Value: FAMPanel);
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Published-Deklarationen }
    property Header: FAMPanel read FHeader write SetHeader;
    property Content: FAMPanel read FContent write SetContent;
    property Footer: FAMPanel read FFooter write SetFooter;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('FAMUI', [FAMCard]);
end;

{ TFamGUI }

constructor FAMCard.Create(AOwner: TComponent);
begin
  inherited;

  // Default size of fam card
  self.Width := 600;
  self.Height := 400;

  // Create header of card
  FHeader := FAMPanel.Create(self);
  FHeader.Parent := self;
  FHeader.Name := 'FHeader';
  FHeader.Color := _CorporateDesign.gray;
  FHeader.Align := alTop;
  FHeader.Height := 90;
  FHeader.SetSubComponent(true);

  // Create content of card
  FContent := FAMPanel.Create(self);
  FContent.Parent := self;
  FContent.Name := 'FContent';
  FContent.Color := _CorporateDesign.white;
  FContent.Align := alclient;
  FContent.SetSubComponent(true);

  // Create footer of card
  FFooter := FAMPanel.Create(self);
  FFooter.Parent := self;
  FFooter.Name := 'FFooter';
  FFooter.Color := _CorporateDesign.gray;
  FFooter.Align := alBottom;
  FFooter.Height := 90;
  FFooter.SetSubComponent(true);

end;

destructor FAMCard.Destroy;
begin
  inherited;

end;

procedure FAMCard.SetContent(const Value: FAMPanel);
begin
  FContent := Value;
end;

procedure FAMCard.SetFooter(const Value: FAMPanel);
begin
  FFooter := Value;
end;

procedure FAMCard.SetHeader(const Value: FAMPanel);
begin
  FHeader := Value;
end;

end.

DeddyH 22. Dez 2014 11:35

AW: Eigene Komponete / Darstellungsfehler?!
 
Damit hast Du Dir aber potentielle Speicherlecks eingebaut. Es wäre besser, nicht die FAMPanels direkt zuzuweisen, sondern nur die Properties für die selbst erstellten Instanzen zu übernehmen (Stichwort Assign). Ansonsten überschreibst Du Dir die Instanzvariablen und hast damit keine Möglichkeit mehr, sie später wieder freizugeben.

FAM 22. Dez 2014 12:09

AW: Eigene Komponete / Darstellungsfehler?!
 
Zitat:

Zitat von DeddyH (Beitrag 1284365)
Damit hast Du Dir aber potentielle Speicherlecks eingebaut. Es wäre besser, nicht die FAMPanels direkt zuzuweisen, sondern nur die Properties für die selbst erstellten Instanzen zu übernehmen (Stichwort Assign). Ansonsten überschreibst Du Dir die Instanzvariablen und hast damit keine Möglichkeit mehr, sie später wieder freizugeben.

kannst du das bitte ein wenig mit hilfe von ein stück sourcecode mir verdeutlichen :)?

reicht das nicht?

Delphi-Quellcode:
destructor FAMCard.Destroy;
begin
  inherited;
  FHeader.Free;
  FContent.Free;
  FFooter.Free;
end;

Uwe Raabe 22. Dez 2014 12:36

AW: Eigene Komponete / Darstellungsfehler?!
 
Das Problem sind die Setter:

Delphi-Quellcode:
procedure FAMCard.SetHeader(const Value: FAMPanel);
begin
  FHeader := Value;
end;
Hier ist der vorige Inhalt von FHeader immer noch instanziert, wird aber nie mehr freigegeben. (Nie, abgesehen davon, daß bei Programmende der Speicher natürlich schon wieder freigegeben wird)


Alternativ:
Delphi-Quellcode:
procedure FAMCard.SetHeader(const Value: FAMPanel);
begin
  FHeader.Free;
  FHeader := Value;
end;
oder
Delphi-Quellcode:
procedure FAMCard.SetHeader(const Value: FAMPanel);
begin
  FHeader.Assign(Value);
end;

himitsu 22. Dez 2014 13:26

AW: Eigene Komponete / Darstellungsfehler?!
 
Dank des Owners wird das schon vorher freigegeben. :zwinker:

Zitat:

Zitat von Uwe Raabe (Beitrag 1284373)
Delphi-Quellcode:
procedure FAMCard.SetHeader(const Value: FAMPanel);
begin
  FHeader.Free;
  FHeader := Value;
end;

Und was wenn man die selbe Instanz reingibt?
Zitat:

Zitat von Uwe Raabe (Beitrag 1284373)
Delphi-Quellcode:
procedure FAMCard.SetHeader(const Value: FAMPanel);
begin
  if FHeader <> Value then
    FreeAndNil(FHeader);
  FHeader := Value;
end;

// oder besser so
procedure FAMCard.SetHeader(const Value: FAMPanel);
begin
  if Assigned(FHeader) and (FHeader.Owner = Self) then
    FreeAndNil(FHeader);
  FHeader := Value;
end;

Wobei hier dein angesprochenes Problem erst Recht gilt, denn wer gibt dann Value frei, wenn die Komponente freigegeben wird.

Aber grundsätzlich bin ich auch für die Assign-Variante, denn das ist eine interne Komponente und die sollte/darf einfach nicht von außen direkt geändert werden können.

PS: Eigentlich braucht man hier garkeinen Setter, denn zum Laden der Property nimmer der DFM-Loader den Getter und weist die Werte den Property der existierenden Instanz zu.
Aber der DFM-Writer ist schon immer totaler Schrott, weil er bei Objekten einen Setter verlangt, denn ohne Diesen werden die Property nicht gespeichert. :wall:

Uwe Raabe 22. Dez 2014 13:30

AW: Eigene Komponete / Darstellungsfehler?!
 
Zitat:

Zitat von himitsu (Beitrag 1284379)
Wobei hier dein angesprochenes Problem erst Recht gilt, denn wer gibt dann Value frei, wenn die Komponente freigegeben wird.

Du hast vollkommen Recht: Ownership ist hier das eigentliche Kriterium.

Sir Rufo 22. Dez 2014 14:19

AW: Eigene Komponete / Darstellungsfehler?!
 
Crosspost http://forum.delphi-treff.de/index.p...442#post442442


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:43 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz