2010-07-02 17 views
15

Entonces, tengo un formulario con algunas docenas de controles y a alguien le gustaría guardar y luego restaurar sus contenidos y configuraciones, qué botón de radio fue seleccionado, cuál era la Posición de ese arriba/abajo, etc.¿Cómo guardar y restaurar un formulario?

I también me gustaría almacenar cualquier entrada agregada a un cuadro de lista en tiempo de ejecución.

¿Cuál es la forma más sencilla de hacerlo? DfmToString y reversa? Escribir/leer un .INI? ¿Algo más?

Respuesta

22

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.

+0

Gracias, eso se ve bien. Ahora voy a envolverlo en un bucle y hacerlo recursivo y estoy listo para ir. – Mawg

+0

¿Por qué establecer Parent en nil antes de liberar un componente secundario? En lugar de todo el ciclo, ¿no funcionaría 'Component.DestroyComponents'? – NGLN

+0

¿Por qué 'LoadComponentFromFile()' agrega 'Component' a la lista' 'Application'' de componentes propios? No debería estar haciendo eso en absoluto. –

2

Es bastante fácil leer/escribir las propiedades de componentes u objetos, o la posición de las formas en el archivo o registro INI. Todo lo que necesitas existe en ayuda. Solo necesita decidir cuándo desea leerlos (al crear, antes de mostrar ...) y almacenarlos (al cerrar, ...). Esto depende de lo que esté guardando/restaurando. Si va a utilizar componentes listos y desea guardar la posición del formulario, asegúrese de comprobar cómo tratan varios monitores. Si lo haces a tu manera, debes encargarte de eso. Por ejemplo, puede tener una computadora portátil y un gran monitor de 22 ", y la posición de un formulario se guardó mientras se usaba su gran monitor. Más tarde, si abre este formulario en la computadora portátil, podría mostrarse la pantalla para que no pueda ver el formulario si este caso no se maneja correctamente.

+0

+1 es un punto bajo, pero me aseguraré de ocuparme de él (en el peor de los casos, el usuario puede editar o cambiar el nombre del archivo guardado) – Mawg

Cuestiones relacionadas