La soluzione di PRUZ è una soluzione pronta, JVCL è open source e l'utilizzo di JvFormStorage è semplice, ma è anche possibile utilizzare il meccanismo di streaming di Delphi senza utilizzare componenti di terze parti. Ecco un esempio:.
procedure SaveComponentToFile(Component: TComponent; const FileName: TFileName);
var
FileStream : TFileStream;
MemStream : TMemoryStream;
begin
MemStream := nil;
if not Assigned(Component) then
raise Exception.Create('Component is not assigned');
FileStream := TFileStream.Create(FileName,fmCreate);
try
MemStream := TMemoryStream.Create;
MemStream.WriteComponent(Component);
MemStream.Position := 0;
ObjectBinaryToText(MemStream, FileStream);
finally
MemStream.Free;
FileStream.Free;
end;
end;
SaveComponentToFile prende un'istanza del componente, oltre a un nome di file, e torrenti la componente nel file, in un testo leggibile
.210
Per caricare il componente dal file, è possibile utilizzare un codice come questo:
procedure LoadComponentFromFile(Component: TComponent; const FileName: TFileName);
var
FileStream : TFileStream;
MemStream : TMemoryStream;
i: Integer;
begin
MemStream := nil;
if not Assigned(Component) then
raise Exception.Create('Component is not assigned');
if FileExists(FileName) then
begin
FileStream := TFileStream.Create(FileName,fmOpenRead);
try
for i := Component.ComponentCount - 1 downto 0 do
begin
if Component.Components[i] is TControl then
TControl(Component.Components[i]).Parent := nil;
Component.Components[i].Free;
end;
MemStream := TMemoryStream.Create;
ObjectTextToBinary(FileStream, MemStream);
MemStream.Position := 0;
MemStream.ReadComponent(Component);
Application.InsertComponent(Component);
finally
MemStream.Free;
FileStream.Free;
end;
end;
end;
LoadComponentFromFile prende un'istanza di componente, e un nome di file, quindi carica il contenuto del file nel componente. Per evitare conflitti di denominazione, siamo liberi di tutti i componenti di proprietà esistenti dell'istanza, prima di caricare i dati del file in esso.
Ora è possibile utilizzare il codice qui sopra per il salvataggio di un modulo in un file:
SaveComponentToFile(FSecondForm,ExtractFilePath(Application.ExeName)+ 'formdata.txt');
FSecondForm è un esempio la forma, e sarà salvato nel file "formdata.txt" all'interno della stessa cartella del File EXE
E per caricare FSecondForm dal file "formdata.txt", scriviamo questo:
if not Assigned(FSecondForm) then
FSecondForm := TfrmSecond.Create(Application);
LoadComponentFromFile(FSecondForm,ExtractFilePath(Application.ExeName)+ 'formdata.txt');
FSecondForm.Show;
LoadComponentFromFile ha bisogno l'istanza deve essere creato prima, quindi controlliamo se viene assegnata FSecondForm, se non, creiamo un istanza di esso (è un'istanza della classe TfrmSecond), quindi carica i dati del file in essa. E alla fine, mostriamo il modulo caricato.
Grazie, sembra buono. Ora lo avvolgerò in un loop e lo renderò ricorsivo e sono pronto per partire. – Mawg
Perché impostare Parent su nil prima di liberare un componente figlio? Invece del ciclo intero for, 'Component.DestroyComponents' non funzionerebbe altrettanto? – NGLN
Perché 'LoadComponentFromFile()' aggiunge 'Component' all'elenco dei componenti di proprietà di' Application'? Non dovrebbe farlo affatto. –