Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Neue visuelle Komponente


jjturbo - Mo 09.12.19 13:20
Titel: Neue visuelle Komponente
Moin Forum,

ich habe mir eine neue Komponente erstellt, abgeleitet von TRect. Sie ist auch registriert und ich kann sie von der Tool-Palette auf mein TForm ziehen. Der constructor "Create" wird durchlaufen und auch afterconstruction. Diverse Eigenschaften werden gesetzt und alles so angezeigt wie ich es gerne hätte.

Wenn ich jetzt mein Progrämmchen starte, dann wird der constructor create noch einmal durchlaufen?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
unit HC_LED_3;

interface


uses FMX.Objects, System.Classes, FMX.Types, FMX.Graphics, System.UITypes,
     system.UIConsts, FMX.StdCtrls, FMX.Dialogs, SysUtils, System.Types;




type
  THC_LED_3 = class(TRectangle)
  private
    fName         :String;
    fText         :String;
    procedure TextGeaendert(Text:String);
  protected
  public
    myLabel       :TLabel;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure afterconstruction; override;
  published
    property AA_Text :String read fText write TextGeaendert;
  end;



procedure Register;


implementation






procedure THC_LED_3.TextGeaendert(Text:String);
var tmpLabel :TLabel;
    i        :Integer;
begin
  fText           := Text;


  if myLabel = nil
   then myLabel := TLabel.Create(Self);

  myLabel.Parent     := Self;
  myLabel.Name       := Name + '_bla_Label';
  myLabel.Anchors    := [TAnchorKind.akLeft, TAnchorKind.akTop];

  myLabel.AutoSize   := True;
  myLabel.Width      := 444;
  myLabel.Text       := Self.ClassName+'/'+myLabel.Name;//fText;

  myLabel.Width      := 100;
  myLabel.Height     := 25;
  myLabel.Position.X := Self.Width + 5;
  myLabel.Position.Y := Self.Height/2 - myLabel.Height/2;

end;







constructor THC_LED_3.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Parent := AOwner as TFmxObject;
  Name   := fName;
end;







procedure THC_LED_3.afterconstruction;
begin
  Width  := 20;
  Height := 25;
end;




destructor THC_LED_3.Destroy;
begin
  FreeAndNil(myLabel);
  inherited destroy;
end;





procedure Register;
begin
  RegisterComponents('Meine Komponenten', [THC_LED_3]);
end;






end.








In_der_IDE







Gestartet


Th69 - Mo 09.12.19 14:16

Selbstverständlich wird der Konstruktor auch aufgerufen, wenn das Programm startet (d.h. zur Laufzeit).
In der IDE wird dieser aufgerufen, damit der Designer überhaupt die Komponente darstellen kann.

Wenn du diesbgzl. unterscheiden möchtest, dann mußt du den "Design-Mode" beachten: TComponentState.csDesigning [http://docwiki.embarcadero.com/Libraries/Rio/en/System.Classes.TComponentState], s.a. Component Initialization - Runtime vs. Designtime [https://stackoverflow.com/questions/691997/component-initialization-runtime-vs-designtime].


Sinspin - Mo 09.12.19 14:25

Hallo, da Du das intern verwendete Label via Create(self) erstellst, darfst du es im Destroy nicht freigeben.
Alles andere hat user profile iconTh69 ja schon gesagt.


jjturbo - Mo 09.12.19 16:22

Weshalb darf ich dann das Label nicht wieder freigeben?

-> Wenn ich das Projekt öffne und wieder schliesse,dann taucht unter HC_LED_31 das Label auf... hängt wohl irgendwie damit zusammen?

Gestartet2


Th69 - Mo 09.12.19 16:50

Es wird bisher zweimal in deinem Code das Label-Objekt freigegeben, da das Label schon von dem übergeordneten Objekt selbst freigegeben wird (da du self als Besitzer/Owner angegeben hast) - und üblicherweise führt das zu einem Speicherzugriffsfehler.


jjturbo - Mi 11.12.19 10:34

Irgendwie verstehe ich es immer noch nicht: Immer wenn ich die Unit schließe auf die ich die Komponente gezogen habe und anschließend wieder öffne habe ich das Label doppelt.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
unit HC_LED_3;

interface


uses FMX.Objects, System.Classes, FMX.Types, FMX.Graphics, System.UITypes,
     system.UIConsts, FMX.StdCtrls, FMX.Dialogs, SysUtils, System.Types;




type
  THC_LED_3 = class(TRectangle)
  private
    myLabel       :TLabel;
    fName         :String;
  protected
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure afterconstruction; override;
  published
  end;



procedure Register;


implementation






constructor THC_LED_3.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Parent := AOwner as TFmxObject;
  Name   := fName;
end;



procedure THC_LED_3.afterconstruction;
begin

  Width  := 20;
  Height := 25;

  if csDesigning in ComponentState then begin
    myLabel := TLabel.Create(Self);
    myLabel.Parent     := Self;
    myLabel.Name       := Name + '_bla_Label';
    myLabel.Anchors    := [TAnchorKind.akLeft, TAnchorKind.akTop];
  end;

end;




destructor THC_LED_3.Destroy;
begin
  inherited destroy;
end;



procedure Register;
begin
  RegisterComponents('Meine Komponenten', [THC_LED_3]);
end;






end.


jaenicke - Mi 11.12.19 15:16

Das liegt schlicht daran, dass das Label zur Designzeit auf dem Formular landet und dementsprechend auch von Delphi gespeichert wird. Dass das von dir dort erstellt wurde, kann die IDE nicht berücksichtigen, wenn du ihr das nicht sagst. Was da ist wird auch gespeichert.

Du kannst aber die Eigenschaft Stored (des Labels) auf False setzen nachdem du das Label erzeugt hast um dies zu verhindern.


jjturbo - Do 12.12.19 09:54

Das war´s was ich suchte!
Danke :-)