Delphi Component Saving - PullRequest
       13

Delphi Component Saving

0 голосов
/ 02 апреля 2009

Как лучше всего сохранить этот компонент и все внутренние переменные? Примеры кода будут оценены.

  TSmall = record
      fName: string[30];
      fAge: integer;
      fID_Number: string[30];
  end;

  TRec = record
    ArraySmall: array[1..10] of TSmall;
  end;

  TBigComponent = class(TComponent)
    private
      fSmallArr: TRec;
      fCompCount: integer;
      fBigName: string;
    public
      procedure AddNew(Name: string; Age: integer; ID: string);
      procedure Save(FileName: string);
      procedure Load(FileName: string);
      procedure SetName(Name: string);
      function GetName: string;
      function ToString: string;
    published
      property SmallArr: TRec read fSmallArr write fSmallArr;
      property Count: integer read fCompCount write fCompCount;
      property Name: string read fBigName write fBigName;
    end;

Ответы [ 3 ]

2 голосов
/ 03 апреля 2009

Небольшое улучшение к предложению Воутера:

 type
  TSmall = record
      fName: string[30];
      fAge: integer;
      fID_Number: string[30];
  end;

  TRec = record
    ArraySmall: array[1..10] of TSmall;
  end;

  TBigComponent = class(TComponent)
  private
      type
        TInternalFields = record
          SmallArr: TRec;
          CompCount: integer;
          BigName: Shortstring;
       end;
    var
      FFields : TInternalFields;
    public
      procedure AddNew(Name: string; Age: integer; ID: string);
      procedure Save(FileName: string);
      procedure Load(FileName: string);
      procedure SetName(Name: string);reintroduce;
      function GetName: string;
      function ToString: string;
    published
      property SmallArr: TRec read FFields.SmallArr write FFields.SmallArr;
      property Count: integer read FFields.CompCount write FFields.CompCount;
      property Name: ShortString read FFields.BigName write FFields.BigName;
    end;

procedure TBigComponent.Save(FileName: string);
var
  F:File of TInternalFields;
begin
  AssignFile(F,FileName);
  Rewrite(F);
  Write(F, FFields);
  CloseFile(F);
end;

Это устраняет необходимость копировать каждое поле из объекта в запись - она ​​уже есть в записи.

Я не уверен, когда был добавлен синтаксис read Record.field - это в 2006

1 голос
/ 02 апреля 2009

В целом, вероятно, проще всего следовать предложению VilleK и использовать то, что предоставляет Tpersistent.

Однако я почему-то предпочитаю этот метод, поэтому я полностью контролирую структуру файла.

type
  TFileStruct=packed record
    fSmallArr: TRec;
    fCompCount: UINT32; // be explicit.. who knows what 64bit Delphi does to your integers...
    fBigName: String[250]; // AnsiChar
  end;

procedure TBigComponent.Save(FileName: string);
var
  F:File of TFileStruct;
  FileStruct:TFileStruct;
begin
  FileStruct.fSmallArr := fSmallArr;
  FileStruct.fCompCount := fCompCount;
  FileStruct.fBigName := fBigName;

  AssignFile(F,FileName);
  Rewrite(F);
  Write(F,FileStruct);
  CloseFile(F);
end;

Имейте в виду, что String [xxx] выглядит как AnsiString, поэтому если вы используете Delphi 2009, ваши строки Unicode будут заменены на AnsiStrings при сохранении. По крайней мере, файлы будут обмениваться с программным обеспечением, скомпилированным с более старыми версиями Delphi.

В TSmall я бы изменил целое число для Age на Byte, чтобы у вас не было проблем с 64-битным Delphi.
«8 битов должно хватить каждому» (с) 2009 Wouter: -)

1 голос
/ 02 апреля 2009

Чтобы использовать внутреннее постоянство Delphi и RTTI, вы должны использовать классы вместо записей.

Здесь много полезных советов и примеров:

Каков хороший способ сериализации дерева объектов Delphi в XML - с использованием RTTI, а не пользовательского кода?

Если вы ищете пример сохранения пользовательских данных в визуальном компоненте, проверьте источник Delphi VCL для метода TTreeNodes.DefineProperties в файле ComCtrls.pas.

...