Hello party people,
also ich bin da auf ein sehr interessantes, wenn auch frustrierendes, und zugleich möglicherweise sogar noch logisches Problem gestoßen, an dem sich jeder gerne versuchen darf
Hintergrund: Entwickelt wurde eine
MDI-Anwendung. In den jeweiligen
MDI-Children werden in zahlreichen Controls Eingaben gemacht, die in ihrer Gesamtheit gespeichert und später wieder geladen werden sollen. Damit ich das nicht in der Manier:
"Schreibe KomponenteX.EigenschaftA in TextDatei t, gehe eine Zeile weiter, Schreibe KomponenteY.EigenschaftB in TextDatei t, gehe ..."
machen muss, habe ich das (auch dank einiger Beispiele von DelphiPraxis
) so gelöst:
Speichern:
Delphi-Quellcode:
procedure TMainForm.FileSaveAs1Execute(Sender: TObject);
var
FileStream : TFilestream;
begin
if SaveDialog1.Execute then
begin
FileStream:=TFileStream.Create(SaveDialog1.Filename, fmCreate);
Try
FileStream.WriteComponent(MainForm.ActiveMDIChild);
Finally
FileStream.Free;
end;
end;
end;
Laden:
Delphi-Quellcode:
procedure TMainForm.ToolButton12Click(Sender: TObject);
var
Child: TForm;
FileStream : TFileStream;
begin
if OpenDialog.Execute then
begin
FileStream:=TFileStream.Create(OpenDialog.Filename, fmOpenRead);
Try
//Eine Instanz eines Unterfensters wird erzeugt
Child := TMDIChild.Create(MainForm);
//Alle Enthaltenen Komponenten darin müssen aber erst gelöscht werden,
//da beim Laden sonst eine Komponente mit demselben Namen schon existieren
//würde. Ist quick'n'dirty, aber es funktioniert erstmal.
While Child.ComponentCount > 0 do
begin
Child.Components[0].Destroy;
end;
//Der Stream mit allen Eigenschaften und Unterkomponenten wird nun in Child hineingelesen
FileStream.ReadComponent(Child);
Finally
FileStream.Free;
end;
end;
end;
So das funktioniert auch soweit schon ganz gut.
Nun aber das Problem:
Aus den gesetzten Eigenschaften werden zur Laufzeit (eigene) Komponenten erzeugt (wen's interessiert: es handelt sich dabei um simple Software-Agenten, die miteinander auf einem simulierten Markt handeln sollen, sowie "Agenten-Pools", dem die Agenten angehören.)
Kurz gesagt werden die dynamisch erzeugten Komponenten weder komplett geschrieben (das ist aber nur ein educated guess, weil ich mir die Datei mal im Wordpad angeschaut hab) noch geladen. Wenn ich das Teil wieder lade, wird nicht mehr "gehandelt".
Nähere Infos:
Es wird zuerst ein Agenten-Pool (auch: "MarketCoordinator") erzeugt. Das ist eine simple Spezialisierung von TComponent mit einigen zusätzlichen Eigenschaften. Der Owner dieser Komponente ist das
MDI-Child. Dann werden die Agenten erzeugt. Auch sie sind Spezialisierungen von TComponent mit einigen eigenschaften und der methode "handeln()". Der Owner eines jeden Agenten ist der angegebene Agenten-Pool.
Der Name und der Typ des Agent-Pools stehen in der gespeicherten Datei an letzter Stelle (siehe Anhang). Mehr aber nicht. Die Agenten tauchen so wie ich das sehe gar nicht auf.
Meine Vermutung:
Ohne euch auf eine falsche Spur zu kriegen! Kann es evtl. daran liegen, dass der Typ TMDIChild zwar mit den einzelnen Controls definiert ist (die stehen ja auch zur Entwurfszeit alle drin in der Definition/Formulardatei), aber nicht mit den dynamisch erzeugten Komponenten? Kann mir das nicht so richtig vorstellen, denn der Agenten-Pool wird ja zumindest mit seinem Namen auch mitgespeichert und der wurde ja dynamisch erzeugt.
Habe auch schon versucht, mit der procedure "setSubComponent" was zu reißen, aber das scheint nichts zu bringen - ist wohl für die Entwurfszeit gedacht