![]() |
readcomponent(ResFile) "heckt" Subkomponenten
Hi, comm.,
habe ein Problem beim Schreiben/Lesen neuer Komponenten
Delphi-Quellcode:
im Formular z.B. mit Buttons:
TTestpanel = class(Tpanel)
private FcheckA: TCheckBox; Fted: TEdit; { private declarations } protected { protected declarations } public { public declarations } published { published declarations } property checkA: TCheckBox read FcheckA write Fchecka; property ted: TEdit read Fted write Fted; constructor create(AOWNER:tcomponent);override; end; constructor TTestpanel.create(AOWNER: tcomponent); begin inherited; FcheckA:=tcheckbox.Create(self); FcheckA.Caption:='A'; // FcheckA.name:='checkA'; InsertControl(FcheckA); fchecka.SetSubComponent(true); fted:=TEdit.Create(Self); Fted.parent:=self; // fted.name:='ted'; Fted.Top:=25; Fted.SetSubComponent(true); AutoSize:=true; end; //.... RegisterClasses([TTestpanel]); schreiben:
Delphi-Quellcode:
lesen:
writeComponentResFile('d:\testpanel.tmp',testpanel1);
//oder auch:fstream.WriteComponent(testpanel1); (fstream:tfilestream) FreeAndNil(testpanel1);
Delphi-Quellcode:
Die Probleme:
testpanel1:=ttestpanel.create(self);
ReadComponentResFile('d:\testpanel.tmp',testpanel1); //oder auch:fstream.readComponent(testpanel1); //oder ohne testpanel1:=ttestpanel.create(self): testpanel1:= // ReadComponentResFile('d:\testpanel.tmp',NIL); //bzw. tespanel1:= fstream.readComponent(NIL); InsertControl(Testpanel1); 1. gebe ich den Subkomponenten in ttestpanel.create einen namen, kommt beim Lesen die Fehlermeldung: "Komponente mit der Bezeichnung 'Name' existiert bereits!" 2. bei namenlosen Subkomponenten erhöht sich die Anzahl der im Panel vorhanden Subkomponenten um 1 - d.h. nach dem ersten schreiben/lesen gibt es zwei tedit's und 2 tcheckboxes usw.. Das liegt daran, daß beim Lesen ttestpanel.create aufgerufen wird - damit auch die beiden Subkompontenten erzeugt werden und dann noch einmal eingelesen werden - haben Sie Namen, geht's schief, haben sie keinen Namen, 'vermehren' sie sich! Wo liegt der Fehler - eigentlich will ich meine neue Komponente nur speichern und wieder einlesen?! Die verschiedenen Varianten des Einlesens haben das gleiche, unerwünschte Ergebnis. Bin gespannt! MfG Uwe |
AW: readcomponent(ResFile) "heckt" Subkomponenten
Hi,
tschuldigung, eine Berichtigumg noch, beim Lesen muß es richtig heißen:
Delphi-Quellcode:
testpanel1:=readComponentResFile('d:\testpanel.tmp',nil) as TTestpanel;
//bzw. testpanel1:=fstream.readComponent(nil) as TTestpanel; man könnte zwar nach Create die subkomponenten löschen
Delphi-Quellcode:
Dann sieht ddie Komponente aus, wie erwartet incl. der Eigenschaften der Subkomponenten.
testpanel1.create(self);
Testpanel1.ted.Free; Testpanel1.checkA.free; readComponentResFile('d:\testpanel.tmp',TTestpanel); Aber dies ist wohl nicht der Sinn vom Speichern und Lesen von Komponenten! MfG Uwe |
AW: readcomponent(ResFile) "heckt" Subkomponenten
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
wenn man deine TTestPanel in einen Stream schreibt und diesen in Text umwandelt bekommt man dies:
Code:
Wie man sieht sind CheckBox und Edit zweimal enthalten. Einmal als SubComponent, wie gewünscht, und einmal als Children, wo das Problem liegt. Ich habe ein Testprogramm angehangen, welches dies zeigt.
object TTestPanel
Left = 0 Top = 0 Width = 123 Height = 51 AutoSize = True TabOrder = 0 checkA.Left = 1 checkA.Top = 1 checkA.Width = 97 checkA.Height = 17 checkA.Caption = 'A' checkA.TabOrder = 0 ted.Left = 1 ted.Top = 26 ted.Width = 121 ted.Height = 24 ted.TabOrder = 1 object TCheckBox Left = 1 Top = 1 Width = 97 Height = 17 Caption = 'A' TabOrder = 0 end object TEdit Left = 1 Top = 26 Width = 121 Height = 24 TabOrder = 1 end end Das Problem mit den Childrens liegt in der Kombination Owner der SubComponents, Root beim Speichern in den Stream und dem
Delphi-Quellcode:
. Der Root beim Speichern ist dein TestPanel, genauso wie der Owner der SubComponents. Und
TWinControl.GetChildren
Delphi-Quellcode:
gibt alle Kinder wieder, wo der Owner derselbe wie der Root ist.
TWinControl.GetChildren
Um das zu lösen entweder den Owner von den SubComponents auf NIL setzen oder die Methode
Delphi-Quellcode:
überschreiben. Die meiner Meinung nach beste Variante des Überschreibens habe ich im angehängten Testprogramm umgesetzt. Das
GetChildren
Delphi-Quellcode:
in Zeile 24 ein kommentieren.
{$DEFINE WithFilter}
einbeliebigername. |
AW: readcomponent(ResFile) "heckt" Subkomponenten
Hi,
@ einbeliebigername:Danke für umfängliche Antwort. Das muß ich mir gaaanz langsam durchlesen. Klingt kompliziert. Owner der Subkomponenten auf nil setzen? z.b. testpanel.ted.owner:=nil ist verboten - nur-Lesen-Eigenschaft! habe die {$IFDEF WithFilter} Methoden auf meine Komponente (ohne zu verstehen) angewendet - funktioniert. Muß man eigentlich die Subkompenenten alle ausschließen? So geht's in meinem Beispiel auch:
Delphi-Quellcode:
Allerdings werden auch mit dem Original-Code die Eigenschaften fcheckA.Checked bzw. ted.text NICHT mitgespeichert!
procedure TTestPanel.FilterGetChildren(Child: TComponent);
begin // if (Child<> Fted) and (Child<> FcheckA) then // fFilterGetChildrenProc(child); end; (In einer anderen Komponente mit noch verzwickteren Childabhängigkeiten geht's dann aber wieder - da muß ich eben gaaanz lange drüber nachdenken) MfG Uwe |
AW: readcomponent(ResFile) "heckt" Subkomponenten
Hi,
muß wohl doch ein Fehler im Package gewesen sein - auch das speichern von checked bzw. text geht nun. Damit wäre das wohl eine Lösung, die man in jede neue Komponente mit einbauen muß, wenn man wincontrols als properties benutzt. Gruß Uwe |
AW: readcomponent(ResFile) "heckt" Subkomponenten
Hallo,
Zitat:
Delphi-Quellcode:
statt so
tcheckbox.Create(nil);
Delphi-Quellcode:
.
tcheckbox.Create(self);
Zitat:
Delphi-Quellcode:
wird vom Streamingsystem aufgerufen und soll für jedes Kind der Komponente die im Parameter Proc angegebene Methode Aufrufen. Diese Methode speichert dann das Kind innerhalb der Komponente. Beim laden werden diese Kinder mittels Create wieder erzeugt.
GetChildren
Zitat:
Zitat:
Delphi-Quellcode:
wäre dasselbe wie:
TTestPanel.FilterGetChildren
Delphi-Quellcode:
Aber meinen Code kann man ja noch vereinfachen bzw. verallgemeinern.
procedure TTestPanel.GetChildren(Proc: TGetChildProc; Root: TComponent);
begin end;
Delphi-Quellcode:
Damit würde man alle SubComponents ausschließen. Diesen Code könnte man bedenkenlos in jeder Komponente Platzieren, da ja SubComponents niemals als Kind, sonder über ein published Property gespeichert werden.
procedure TTestPanel.FilterGetChildren(Child: TComponent);
begin if not csSubComponent in Child.ComponentStyle then fFilterGetChildrenProc(child); end; Und wenn man sich das ganze nochmal durch den Kopf gehen lässt, wäre damit eigentlich die Implementierung von
Delphi-Quellcode:
in
GetChildren
Delphi-Quellcode:
fehlerhaft.
TWinControl
einbeliebigername. |
AW: readcomponent(ResFile) "heckt" Subkomponenten
Hi,
schnell ein Test - nicht viel Zeit! Ich habe erstmal die Procedure wiederhergestellt:
Delphi-Quellcode:
und im Formulardesigner eine weitere Tcheckbox im tpanel plaziert:
procedure TTestpanel_UA.FilterGetChildren(Child: TComponent);
begin if (Child<> Fted) and (Child<> FcheckA) then fFilterGetChildrenProc(child); end; Diese wird nicht (!) gespeichert. Vieleicht wegen ...as ttestpanel_UA? Gruß Uwe |
AW: readcomponent(ResFile) "heckt" Subkomponenten
Hallo,
Zitat:
Beim ersteren sollte mit entweder
Delphi-Quellcode:
oder
procedure TTestPanel.FilterGetChildren(Child: TComponent);
begin if (Child<> Fted) and (Child<> FcheckA) then fFilterGetChildrenProc(child); end;
Delphi-Quellcode:
die weitere CheckBox im Formular gespeichert werden und mit
procedure TTestPanel.FilterGetChildren(Child: TComponent);
begin if not csSubComponent in Child.ComponentStyle then fFilterGetChildrenProc(child); end;
Delphi-Quellcode:
oder
procedure TTestPanel.FilterGetChildren(Child: TComponent);
begin // if (Child<> Fted) and (Child<> FcheckA) then // fFilterGetChildrenProc(child); end;
Delphi-Quellcode:
die weitere CheckBox nicht im Formular gespeichert werden.
procedure TTestPanel.GetChildren(Proc: TGetChildProc; Root: TComponent);
begin end; Beim zweitem wird die weitere CheckBox nie gespeichert, da der Owner dieser das Formular ist und der Root beim Speichern das Panel ist. einbeliebigername. |
AW: readcomponent(ResFile) "heckt" Subkomponenten
Hallo,
@einbeliebigerName: alles so, wie oben beschrieben, hatte nicht geschnallt, daß es in dem einen Fall um's Speichern in's Formular ging. Interessant ist, daß wenn man in der IDE-Umgebung
Delphi-Quellcode:
wieder auskommentiert, auf dem Formular die zusätzliche Checkbox erhalten bleibt, zur Laufzeit ist sie dann weg - und erst recht, wenn das Formular gespeichert wurde.
procedure TTestpanel_UA.FilterGetChildren(Child: TComponent);
begin end; Problem gelöst - danke an einbeliebigerName! Nebenher - beim Programmieren von Objekten taucht einem ja ständig nach der einen die nächste Frage vor den Füßen auf:
Delphi-Quellcode:
Also als Reaktion auf Checkboxclick wieder zu Ted zurückkehren und alte Verhältnisse wieder herstellen.
{...}
published { published declarations } property checkA: TCheckBox read FcheckA write Fchecka; property ted: TEdit read Fted write Fted; constructor create(AOWNER:tcomponent);override; {!} procedure oncheckboxclick(Sender: TObject);virtual; constructor TTestpanel_UA.create(AOWNER: tcomponent); begin {...} FcheckA.OnClick:=oncheckboxclick; AutoSize:=true; end; procedure TTestpanel_UA.oncheckboxclick(Sender: TObject); var oldss,oldsell:integer; begin try //geht hier bei der Initialisierung noch schief, da noch kein Fenster da ist with Fted do begin oldss:=SelStart;oldsell:=sellength; setfocus; selstart:=oldss; SelLength:=oldsell; end; except end; end; Ist fcheckA.checked=TRUE und speichert man zur Laufzeit testpanel ab und lädt es dann wieder, so geht das ohne try except schief mit der Meldung: "Fehler beim Lesen von testpanel_ua1.checka.checked: Element Testpanel_ua1 hat kein übergeordnetes Fenster." Wie kann man ermitteln, wann das übergeordnete Fenster da ist, um soche Ausnahmen zu verhindern? Ich würde den eigentlich Thread eigentlich als beantwortet markieren wollen - dank der Arbeit von einbeliebigerName, finde aber 'grad nicht, wo das passieren kann ... Gruß Uwe |
AW: readcomponent(ResFile) "heckt" Subkomponenten
Hallo,
mach mal bitte dazu ein neues Thema auf. Das wird hier nicht gern gesehen, denn es ist ein neues Problem und hat mit den SubComponents nichts zu tun. Im Moment habe ich da auch noch keine Idee. einbeliebigername. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:11 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz