Autor Beitrag
Aya
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Mo 17.03.03 05:31 
Hi,

ich bin mittlerweile fast am verzweifeln mit einem Fehler in der Komponenten Entwicklung....

Selbst die Borland Mitarbeiter auf der CeBit konnten mir nich weiterhelfen.. (Sie haben mir zwar div. sachen gesagt, was ich machen solle, aber hat alles nix gebracht)

Also...
Mal als Beispiel:

Ich leite eine Komponente von eim TPanel ab, und erstelle in dieser Komponente eine Variable und einen Constructor:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
type
  TTestPanel = class(TPanel)
  private
    { Private declarations }
    P: TPanel;
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
  published
    { Published declarations }
  end;

Soweit sogut... wenn ich nun im Constructor aber das Panel "P" erstelle:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
constructor TTestPanel.Create(AOwner: TComponent);
begin
  Inherited;
  P:=TPanel.Create(self);
  P.Parent:=self;
  P.Height:=40;
end;

wird zwar alles korrekt angezeigt später, aber..!
Wenn ich z.B. ein TLabel auf die Komponente per Drag&Drop draufpacke...
lege ich sie auf die Komponente auf sich, is alles wunderbar... lege ich das Label aber auf das Panel "P" innerhalb meiner Komponente, und starte das Programm dann... dann ist es, als hätte ich das Label nie erstellt...

Es ist weder sichtbar, noch kann ich auf Label1.Name o.ä. zugreifen...
Wenn ich das Projekt speichere, und mir dann die Source (speziell die DFM Datei) angucke, ist dort keine Spurt von meinem Label...

Ich halte das ganze ja für einen Bug.. *g* Aber, KA...
Wenn jemand eine lösung weiß, bitte... ich such da schon ewig verzweifelt nach :(

Au'revoir,
Aya~

_________________
Aya
I aim for my endless dreams and I know they will come true!
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 17.03.03 05:54 
Label zur Laufzeit erstellen. Ist aber auch keine Lösung, wenn du die Komponente weitergeben willst.

Wie sieht es den mit anderen Komponenetn aus?
Klabautermann
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Veteran
Beiträge: 6366
Erhaltene Danke: 60

Windows 7, Ubuntu
Delphi 7 Prof.
BeitragVerfasst: Mo 17.03.03 10:48 
Hallo,

vieleicht wird das neu erzeugte Label mit Parent=Form angelegt, und liegt deshalb hinter deinem Panel.
Vieleicht musst du den Parent des Panels nicht auf Self setzen sondern auf Self.Parent.
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
constructor TTestPanel.Create(AOwner: TComponent);
begin
 Inherited;
 P:=TPanel.Create(self);
 P.Parent:=self.Parent;
 P.Height:=40;
end;

Das ist zwar nur so'ne Idee, aber vieleicht lande ich ja 'nen Glückstreffer.

Gruß
Klabautermann
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Mo 17.03.03 12:21 
Sind zwar jetzt auch nur Vermutungen, aber so schaut mal meine (Fern)analyse aus..

Die Form die du zur Design-Time erstellst wird ja in der DFM-Datei gespeichert. In dieser DFM-Datei steht dann deine Form mit allen Eigenschaften und alle Komponenten, die auf deiner Form drauf sind (auch mit ihren Eigenschaften). Deine Komponente erzeugt jetzt noch eine Instanz einer Komponente, welche allerdings nur intern innerhalb deiner Komponente verwendet wird, und von Delphi daher nicht als solche erkannt und in der DFM-Datei gespeichert wird. Das Label allerdings müsste schon in die DFM-Datei kommen, aber da das Panel aus deiner Komponente nicht auftaucht weiß Delphi nicht wo es das Label in der DFM-Datei hinschreiben soll.

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
Aya Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Mo 17.03.03 18:48 
huhu,

hab die ganzen sachen mal ausprobiert, hat aber leider alles nix geholfen... das Label verschwindet immernoch :cry:

Au'revoir,
Aya~

_________________
Aya
I aim for my endless dreams and I know they will come true!
Leuselator
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Di 18.03.03 13:22 
Titel: Halleluja - ich bin niocht allein!
Hi alle!

Schön, dass ich nicht der einzige Dumme auf der Welt bin :D
Habe das gleiche Problem mit selbstgebauten Komponenten.
Zum Beispiel TTestPanel mit darauf plaziertem Child-TPanel:
Plaziere ich zur Entwurfszeit ein (z.B.) TEdit auf dem TTestPanel so ist es zur Laufzeit sichtbar - plaziere ich das TEdit auf ChildPanel so "verschwindet" es zur Laufzeit im Nirvana.
Am Borland-Stand auf der C-Bit konnte man mir damit nicht helfen...

Ich denke, dass Motzi auf der richtigen Fährte ist. Die Frage bleibt, wie ich in das DFM-Streaming eingreifen und die zur Entwurfszeit plazierten Controls dort abspeichern kann.

ausblenden volle Höhe 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:
unit TestPanel; 

interface 

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

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

procedure Register; 

implementation 

constructor TTestPanel.Create(AOwner: TComponent); 
begin 
  inherited create(AOwner); 
  width := 400; 
  Height := 200; 
  ChildPanel := TPanel.create(self); 
  ChildPanel.Parent := self; 
  ChildPanel.left := 5; 
  ChildPanel.Top:=5; 
  ChildPanel.Width := 190; 
  ChildPanel.Height := 190; 
  ChildPanel.Caption := 'Childpanel looses its controls'; 
end; 

destructor TTestPanel.destroy; 
begin 
  ChildPanel.Free; 
  inherited; 
end; 

procedure Register; 
begin 
  RegisterComponents('TestPanel', [TTestPanel]); 
end; 

end.
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Di 18.03.03 13:57 
Titel: Re: Halleluja - ich bin niocht allein!
Leuselator hat folgendes geschrieben:
Ich denke, dass Motzi auf der richtigen Fährte ist. Die Frage bleibt, wie ich in das DFM-Streaming eingreifen und die zur Entwurfszeit plazierten Controls dort abspeichern kann.

Wenn dem so ist, so wird dir ein Eingreifen ins DFM-Streaming wahrscheinlich auch nicht helfen (sondern eher noch größere Probeleme machen). Denn wenn du ins DFM-Streaming eingreifst und dein ChildPanel einträgst, so wird Delphi beim nächsten öffnen der DFM dein ChildPanel automatisch erstellen, während du es in deinem Konstruktor auch nochmal erstellst... (könnte ich mir zumindest gut vorstellen)

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
Leuselator
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Di 18.03.03 14:05 
Und wat nu???
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Di 18.03.03 15:13 
Willst du nur auf einem Panel Komponenten ablegen können oder auf beiden (also sowohl TestPanel als auch ChildPanel)?

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
Aya Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Di 18.03.03 16:36 
Motzi hat folgendes geschrieben:
Willst du nur auf einem Panel Komponenten ablegen können oder auf beiden (also sowohl TestPanel als auch ChildPanel)?

In meinem fall würde mir ChildPanel reichen :)

_________________
Aya
I aim for my endless dreams and I know they will come true!
Leuselator
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Di 18.03.03 16:54 
Das Problem ist bei mir wohl das allgemeine Verständnis der Abspeicherung der zur Entwurfszeit auf einem Formular plazierten Komponenten und der Mechanismus deren Erzeugung zur Laufzeit.
Die Hilfe ist in diesem Bereich ein einziger weisser Fleck auf der Landkarte
Ich nahm bisher an, das dies die IDE erledigt (zeigt Sie die Sachen zur Entwurfszeit ja richtig an) und da ich von TPanel ableite dachte ich, die Mechanismen zur Speicherung würden auch für Kindelemente automatisch funzen. Geht aber wohl nicht so einfach.
Es muß doch irgendwie mit dem Formularstreaming zu tun haben - ich erzeuge zwar das Kindpanel "dynamisch" in der Komponente, aber die zur Entwurfszeit plazierten Controls sind eben nicht dynamisch. Irgendwie muß nach dem Create (Loaded?) eine Routine rein, die dafür sorgt, das die in der IDE plazierten Controls in das Child geladen werden. Dazu müssen sie aber zunext erstmal in die DFM wandern (?) und wie ich das machen soll (müßte ja von der IDE zur Entwurfs- bzw. Compilierzeit getan werden ?!) ist mir ein einziges Rätsel.
Schleppe das Prolem auch schon 2 Jahre mit mir rum...
Aya Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Di 18.03.03 18:35 
Ich hab es hinbekommen!!! 8)

und zwaaaar....

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
constructor TTestPanel.Create(AOwner: TComponent); 
begin 
  Inherited; 
  P:=TPanel.Create(Owner);  // <- Owner!! nicht self
  P.Parent:=self; 
  P.Height:=40; 
end;


Bei mir klappt das wunderbar :)

Au'revoir,
Aya~

_________________
Aya
I aim for my endless dreams and I know they will come true!
LarsMiddendorf
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Di 18.03.03 18:37 
Man könnte mal versuchen die Methoden TComponent.GetChildren und TComponent.GetChildOwner zu überschreiben. Diese werden vom Streaming-System aufgerufen, um die untergeordneten Componenten zu speichern. Normalerweise ist die Methode GetChildren leer. Der Owner des untergeordneten ChildPanel ist das Panel, deshalb ist das TTestPanel auch für die Speicherung des ChildPanel verantwortlich und nicht das Formular.

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TTestPanel.GetChildren(proc:TGetChildProc;root:TComponent);
var
i:integer;
begin
for i:=0 to ComponentCount-1 do
  proc(Components[i]);
end;


Außerdem muß man noch die Methode GetChildOwner überschreiben, damit das Streaming System weiß, das der Owner der untergeordneten Komponenten nicht das Formular sondern das TestPanel ist.

ausblenden Quelltext
1:
2:
3:
4:
function TTestPanel.GetChildOwner:TComponent;
begin
result:=self;
end;


Moderiert von user profile iconKlabautermann: Code-Tags hinzugefügt.
Leuselator
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Di 18.03.03 19:29 
Hmm - weder das Eine (Owner) noch das Andere (GetChildren) funzt bei mir :-(
Leuselator
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Mi 19.03.03 15:33 
Ok - mit
ausblenden Quelltext
1:
2:
initialization
RegisterClass(TPanel);

Funzt die Create(MotherPanel.Owner)-Variante doch (kein EClassNotFound Error mehr).

Auf diese Art bekommt man in der IDE jedoch Zugriff auf das ChildPanel
und kann es dort (mit fataler Folge) z.B. auch löschen = nicht gewollt.

Werde mich wohl doch nochmal der GetChild-Variante widmen...
LarsMiddendorf
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Fr 21.03.03 18:19 
Natürlich die Klasse muß erst registriert werden.

Bei Delphi ist in der Unit extctrls die TLabeledEdit Komponente. Das ist ein TEdit mit integriertem Label. Der Label ist eine Subkomponente,dessen Eigenschaften zwar im Objekt-Inspektor bearbeiten werden können, die aber nicht gelöscht werden kann. Mit TComponent.SetSubComponent(True) setzt man eine Komponente als Subkomponente. Bei Subkomponenten braucht man glaube ich auch nicht GetChildOwner und GetChildren zu übetschreiben, weil das Streaming System Subkomponenten automatisch speichert.