Reputation:
How best could I save this component and all internal variables? Examples of code would be appreciated.
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;
Upvotes: 0
Views: 2395
Reputation: 5975
A small enhancement to Wouter's suggestion:
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;
This removes the need to copy each field from the object into a record - it is already in a record.
I'm not sure when the read Record.field syntax was added - it is in 2006
Upvotes: 2
Reputation: 24086
In general, it's probably the easiest to follow VilleK's suggestion, and make use of what Tpersistent provides.
However, I somehow prefer this method, so I keep full control over the structure of the file.
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;
Keep in mind that String[xxx] seems to be treated like AnsiString, so if you use Delphi 2009, your Unicode strings will be changed into AnsiStrings when you save. At least files will be exchangable with software that's compiled with older versions of Delphi.
In TSmall I'd change the integer for Age to Byte, so that you won't get in trouble with 64bit Delphi.
"8 bits should be enough for everyone" (c) 2009 Wouter :-)
Upvotes: 1
Reputation: 7131
To make use of Delphi internal persistence and RTTI you should use classes instead of records.
There are lots of good advice and examples here:
What's a good way to serialize Delphi object tree to XML--using RTTI and not custom code?
If you are looking for an example of saving custom data to a visual component, check the Delphi VCL source for method TTreeNodes.DefineProperties in file ComCtrls.pas.
Upvotes: 1