2010-07-02 3 views
15

Donc, j'ai un formulaire avec quelques douzaines de contrôles et quelqu'un voudrait enregistrer et restaurer plus tard leurs contenus et paramètres - quel bouton radio a été sélectionné, quelle était la position de ce haut/bas, etcComment sauvegarder et restaurer un formulaire?

I souhaite également stocker toutes les entrées ajoutées à une zone de liste lors de l'exécution.

Quelle est la manière la plus simple de le faire? DfmToString et inverse? Écrire/lire un .INI? Autre chose?

Répondre

22

La solution de PRUZ est une solution prête à l'emploi, JVCL est open-source et JvFormStorage est simple, mais vous pouvez également utiliser le mécanisme de streaming de Delphi sans utiliser de composants tiers. Voici un exemple:.

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 prend une instance de composant, plus un nom de fichier, et les flux du composant dans le fichier, dans un texte lisible par l'homme

Pour charger le composant de fichier, vous pouvez utiliser un code comme ceci:

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 prend une instance de composant, et un nom de fichier, charge ensuite le contenu du fichier dans l'instance du composant. Pour éviter les conflits de noms, nous libérons tous les composants appartenant à l'instance, avant de charger les données du fichier.

Maintenant, vous pouvez utiliser le code ci-dessus pour enregistrer un formulaire dans un fichier:

SaveComponentToFile(FSecondForm,ExtractFilePath(Application.ExeName)+ 'formdata.txt'); 

FSecondForm est une instance de forme, et il sera enregistré dans le fichier « formdata.txt » dans le même dossier que le Fichier EXE.

Et pour charger FSecondForm du fichier « formdata.txt », nous écrivons ceci:

if not Assigned(FSecondForm) then 
    FSecondForm := TfrmSecond.Create(Application); 
    LoadComponentFromFile(FSecondForm,ExtractFilePath(Application.ExeName)+ 'formdata.txt'); 
    FSecondForm.Show; 

LoadComponentFromFile a besoin de l'instance à créer d'abord, donc, nous vérifions si FSecondForm est attribué, sinon, nous créons une instance de celui-ci (c'est une instance de classe TfrmSecond), puis charger des données de fichier dans celui-ci. Et finalement, nous montrons le formulaire chargé.

+0

Merci, ça a l'air bien. Maintenant, je vais juste l'emballer dans une boucle et le rendre récursif et je suis prêt à partir. – Mawg

+0

Pourquoi mettre Parent à zéro avant de libérer un composant enfant? Au lieu de la boucle for entière, 'Component.DestroyComponents' ne ferait-il pas aussi bien l'affaire? – NGLN

+0

Pourquoi 'LoadComponentFromFile()' ajoute-t-il '' Component' à la liste des composants possédés par 'Application'? Cela ne devrait pas être du tout le cas. –

2

Il est assez facile de lire/écrire des propriétés de composants ou d'objets, ou de positionner des formulaires dans un fichier ou un registre INI. Tout ce dont vous avez besoin existe en aide. Vous avez juste besoin de décider quand vous voulez les lire (sur la création, avant de les montrer ...) et les stocker (sur close, ...). Cela dépend de ce que vous enregistrez/restaurez. Si vous souhaitez utiliser des composants prêts à l'emploi et que vous souhaitez enregistrer la position du formulaire, assurez-vous de vérifier comment ils traitent plusieurs moniteurs. Si vous le faites à votre façon, vous devriez en prendre soin vous-même. Par exemple, vous pourriez avoir un ordinateur portable et un grand moniteur de 22 ", et la position d'un formulaire a été sauvegardée pendant que votre grand écran était utilisé Plus tard, si vous ouvrez ce formulaire sur un ordinateur portable, il peut s'afficher Formulaire si ce cas n'est pas géré correctement

+0

+1 c'est un coureur à faible, mais je vais être sûr de m'en occuper (dans le pire des cas, l'utilisateur peut modifier ou renommer le fichier de sauvegarde) – Mawg

Questions connexes