如何保存和恢复表单?

时间:2010-07-02 06:12:25

标签: delphi

所以,我有一个包含几十个控件的表单,有人想保存并稍后恢复其内容和设置 - 选择哪个单选按钮,上/下的位置等等。

我还想在运行时存储添加到列表框的所有条目。

最简单的方法是什么? DfmToString和反向?写/读一个.INI?还有别的吗?

2 个答案:

答案 0 :(得分:24)

PRUZ的解决方案是现成的解决方案; JVCL是开源的,使用JvFormStorage很简单。但您也可以使用Delphi自己的流机制,而无需使用任何第三方组件。这是一个例子:

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接受组件实例和文件名,并以人类可读的文本将组件流式传输到文件中。

要从文件加载组件,您可以使用如下代码:

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接受组件实例和文件名,然后将文件内容加载到组件实例中。为避免命名冲突,在将文件数据加载到实例中之前,我们释放实例的所有现有所有组件。

现在您可以使用上面的代码将表单保存到文件中:

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

FSecondForm是一个表单实例,它将保存到与EXE文件相同的文件夹中的“formdata.txt”文件中。

要从“formdata.txt”文件加载FSecondForm,我们写下:

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

LoadComponentFromFile需要首先创建实例,因此我们检查是否分配了FSecondForm,如果没有,我们创建它的实例(它是TfrmSecond类的实例),然后将文件数据加载到其中。最后,我们会显示加载的表单。

答案 1 :(得分:2)

读取/写入组件或对象属性,或在INI文件或注册表中形成位置非常容易。你需要的一切都存在于帮助中。您只需要决定何时阅读它们(在创建之前,在显示之前......)并存储它们(关闭时......)。这取决于您保存/恢复的内容。 如果您打算使用现成的组件并希望保存表单位置,请务必检查它们如何处理多个监视器。如果你按照自己的方式做,你应该自己照顾。例如,您可能有一台笔记本电脑和一台22英寸大显示器,并且在使用大显示器时保存了表单的位置。稍后,如果您在笔记本电脑上打开此表单,则可能会显示屏幕,因此您无法看到如果这种情况处理不当,请填写表格。