![]() |
Sub-Komponenten serialisieren
Hallo, ich habe folgende Konstellation:
Delphi-Quellcode:
das will ich speichern und vor allem laden:
type
TBaseFormElementManager = class abstract(TComponent) protected FControl: TControl; //<--- der da FNaturalDimensions: TDRect; MouseUpEvents: TEventList; MouseDownEvents: TEventList; MouseMoveEvents: TEventList; public procedure SetElement(Value: TControl); virtual; function GetElement: TControl; virtual; procedure SetLeftMm(Value: Double); procedure SetTopMm(Value: Double); procedure SetWidthMm(Value: Double); procedure SetHeightMm(Value: Double); procedure SetLeftPx(Value: Integer); //<--- hier procedure SetTopPx(Value: Integer); procedure SetWidthPx(Value: Integer); procedure SetHeightPx(Value: Integer);
Delphi-Quellcode:
procedure TFormElementSupplier.Save(FileName: string);
var i,size: Integer; m: TBaseFormElementManager; ms,msc: TMemoryStream; begin ms := TMemoryStream.Create; msc := TMemoryStream.Create; try for i := 0 to Elements.Count -1 do begin ms.Size := 0; ms.WriteComponent(Elements[i]); ms.Position := 0; size := ms.Size; msc.Write(size,SizeOf(size)); msc.CopyFrom(ms, size); end; msc.Position := 0; msc.SaveToFile(FileName); finally ms.Free; msc.Free; end; end;
Delphi-Quellcode:
Im ReadComponent wird aber gleich ins SetLeftPx gesprungen, was ich auch nachvollziehen kann:
procedure TFormElementSupplier.Load(FileName: string);
var c: TComponent; ms,msc: TMemoryStream; size: Integer; begin ms := TMemoryStream.Create; msc := TMemoryStream.Create; try ms.LoadFromFile(FileName); while ms.Position < ms.Size do begin ms.Read(size,SizeOf(size)); msc.Clear; msc.CopyFrom(ms,size); msc.Position := 0; c := nil; c := msc.ReadComponent(nil); //<--- HIER Elements.Add(c as TBaseFormElementManager); end; finally ms.Free; msc.Free; end; end;
Delphi-Quellcode:
Wo dann FControl auf nil ausgewertet wird und die Exception kommt.
procedure TBaseFormElementManager.SetLeftPx(Value: Integer);
begin if Assigned(FControl) then FControl.Left := Value else raise EElementNotCreated.Create('No Element Created yet.'); end; Wie bringe ich das ganze System dazu, dass das Control ordentlich zugewiesen wird? Bzw. überhaupt mitgespeichert, ich weiß ja nicht, ob das überhaupt passiert. Ich sollte vielleicht noch einmal erwähnen, dass TBaseFormElementManager nie instanziiert wird, sondern es sich immer um nachfahren handelt. EDIT: hab inzwischen "Setsubcomponent" gefunden... ändert nix... :gruebel: |
Re: Sub-Komponenten serialisieren
Niemand einen Tipp für mich?
|
Re: Sub-Komponenten serialisieren
Zitat:
|
Re: Sub-Komponenten serialisieren
published property ist es deswegen, weil ich sie veröffentlichen will ;)
Ich will es im jedi-runtime-OI drin haben(TJvInspector, imo), allerdings nicht das komplette Control, sondern eben nur ausgewählte über diesen Umweg. Ich werde wohl einfach noch irgendwie eine Weiche einbauen, die mir sagt, dass gerade deserialisiert wird. dann muss ich nicht die exception werfen... |
Re: Sub-Komponenten serialisieren
Hab ich doch glatt vergessen, dass in Delphi OI-Binding und Serialization dämlicherweise verbunden sind :duck: .
Da du also nicht die Serialisierung von Left verhindern kannst, musst du - wie du schon selbst erkannt hast - stattdessen die Property beim Deserialisieren ignorieren -> TComponentState.csReading. |
Re: Sub-Komponenten serialisieren
Das Problem ist IMHO, dass du - wo wies aussieht das Control zur Designtime erstellst und dann der property zuweist. Wenn das Objekt dann wieder deserialisiert wird, is der Pointer noch nil ==> AV.
Du müsstest also sicherstellen, dass zum Zeitpunkt des Zugriffs - am besten schon im Konstruktor - der Property n Control zugewiesen wurde. Also entweder im Konstruktor das Control zuweisen oder gleich dort erstellen... mfg Christian |
Re: Sub-Komponenten serialisieren
Zitat:
Zitat:
|
Re: Sub-Komponenten serialisieren
Zitat:
Zitat:
Spaß beiseite: IMHO wird durch ReadComponent nur das serialisierte Objekt *ohne* Unterobjekte created. Für das Createn der Unterobjekte is das Objekt selbst verantwortlich. Wenn also das Control nicht im Konstruktor erstellt wird und auch sonst nirgendwo, dann produziert ReadComponent eine Exception, weil es ein bereits erstelltes Objekt erwartet, aber nicht findet... mfg Christian |
Re: Sub-Komponenten serialisieren
SetSubComponent sollte doch eigentlich genau das machen...
Wie bereits gesagt, ich werde jetzt eine globale variable "IsUnserializing" einführen, die in der initialization auf false, beim laden auf true setzen und das ganze entsprechend behandeln. |
Re: Sub-Komponenten serialisieren
Zitat:
Zitat:
mfg Christian |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:23 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