La solución de PRUZ es una solución preparada, JVCL es de código abierto y usar JvFormStorage es simple. Pero también puede usar el propio mecanismo de transmisión de Delphi sin usar componentes de terceros. aquí está un ejemplo:.
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 toma una instancia de componente, además de un nombre de archivo, y transmite el componente en el archivo, en un texto legible
Para cargar el componente de archivo, se puede utilizar un código como el siguiente:
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 toma una instancia de componente, y un nombre de archivo, a continuación, carga el contenido del archivo en la instancia del componente. Para evitar el nombramiento de conflictos, todos los componentes existentes de la instancia son libres, antes de cargar datos de archivos en él.
Ahora puede utilizar el código anterior para guardar un formulario en un archivo:
SaveComponentToFile(FSecondForm,ExtractFilePath(Application.ExeName)+ 'formdata.txt');
FSecondForm es una instancia de formulario, y se guardará en un archivo "formdata.txt" dentro de la misma carpeta que el Archivo EXE.
Y para cargar FSecondForm de archivo "formdata.txt", escribimos esto:
if not Assigned(FSecondForm) then
FSecondForm := TfrmSecond.Create(Application);
LoadComponentFromFile(FSecondForm,ExtractFilePath(Application.ExeName)+ 'formdata.txt');
FSecondForm.Show;
LoadComponentFromFile necesita la instancia a crear en primer lugar, por lo que comprobamos si se asigna FSecondForm, si no, creamos una instancia de la misma (es una instancia de clase TfrmSecond), y luego cargar datos de archivos en ella. Y, finalmente, mostramos la forma cargada.
Gracias, eso se ve bien. Ahora voy a envolverlo en un bucle y hacerlo recursivo y estoy listo para ir. – Mawg
¿Por qué establecer Parent en nil antes de liberar un componente secundario? En lugar de todo el ciclo, ¿no funcionaría 'Component.DestroyComponents'? – NGLN
¿Por qué 'LoadComponentFromFile()' agrega 'Component' a la lista' 'Application'' de componentes propios? No debería estar haciendo eso en absoluto. –