Delphi 组件保存
Posted
技术标签:
【中文标题】Delphi 组件保存【英文标题】:Delphi Component Saving 【发布时间】:2009-04-02 10:37:15 【问题描述】:如何才能最好地保存此组件和所有内部变量?代码示例将不胜感激。
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;
【问题讨论】:
【参考方案1】:对 Wouter 建议的一个小改进:
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 年
【讨论】:
感谢您指出这一点 - 我不知道读取 Record.field 语法。【参考方案2】:要使用 Delphi 内部持久性和 RTTI,您应该使用类而不是记录。
这里有很多很好的建议和例子:
What's a good way to serialize Delphi object tree to XML--using RTTI and not custom code?
如果您正在寻找将自定义数据保存到可视组件的示例,请检查 Delphi VCL 源代码中的方法 TTreeNodes.DefineProperties 文件 ComCtrls.pas。
【讨论】:
【参考方案3】:总的来说,遵循 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 位应该对每个人都足够了”(c) 2009 Wouter :-)
【讨论】:
(离题)根据 David I,整数将保持 32 位以上是关于Delphi 组件保存的主要内容,如果未能解决你的问题,请参考以下文章
Delphi之创建组件模板(Component Template)