Delphi应用程序配置的最佳方法是什么? [英] What is the best way to serialize Delphi application configuration?
问题描述
目标:可读的配置类(如INI文件),但无需编写(并在添加新配置项后调整)加载和保存方法。
我想创建一个类,如
TMyConfiguration = class(TConfiguration)
...
属性ShowFlags:Boolean读取FShowFlags写入FShowFlags;
属性NumFlags:整数读取FNumFlags写入FNumFlags;
结束
调用TMyConfiguration.Save(继承自TConfiguration)应该创建一个像
[选项]
ShowFlags = 1
NumFlags = 42
问题:最好的方法是什么?
这是我提出的解决方案。
我有一个基础课程
TConfiguration = class
protected
type
TCustomSaveMethod = function(Self:TObject; P:Pointer):String;
TCustomLoadMethod = procedure(Self:TObject; const Str:String);
public
程序保存(const FileName:String);
程序加载(const FileName:String);
结束
加载方法看起来像这样(相应地保存方法):
程序TConfiguration.Load(const FileName:String);
const
PropNotFound ='_PROP_NOT_FOUND_';
var
IniFile:TIniFile;
计数:整数;
列表:PPropList;
TypeName,PropName,InputString,MethodName:String;
LoadMethod:TCustomLoadMethod;
begin
IniFile:= TIniFile.Create(FileName);
try
计数:= GetPropList(Self.ClassInfo,tkProperties,nil);
GetMem(List,Count * SizeOf(PPropInfo));
try
GetPropList(Self.ClassInfo,tkProperties,List);
for I:= 0 to Count-1 do
begin
TypeName:= String(List [I] ^。PropType ^ .Name);
PropName:= String(List [I] ^。Name);
InputString:= IniFile.ReadString('Options',PropName,PropNotFound);
if(InputString = PropNotFound)then
继续;
MethodName:='Load'+ TypeName;
LoadMethod:= Self.MethodAddress(MethodName);
如果没有分配(LoadMethod)然后
raise EConfigLoadError.Create('自定义类型的无负载方法'+ TypeName);
LoadMethod(Self,InputString);
结束
finally
FreeMem(List,Count * SizeOf(PPropInfo));
结束
finally
FreeAndNil(IniFile);
结束
基类可以为delphi默认类型提供加载和保存方法。然后,我可以为我的应用程序创建一个配置:
TMyConfiguration = class(TConfiguration)
...
发布
函数SaveTObject(P:指针):String;
程序LoadTObject(const Str:String);
发布
属性BoolOption:Boolean读取FBoolOption写入FBoolOption;
属性ObjOption:TObject读取FObjOption写入FObjOption;
结束
自定义保存方法的示例:
function TMyConfiguration.SaveTObject(P:Pointer):String;
var
Obj:TObject;
begin
Obj:= TObject(P);
结果:= Obj.ClassName; //没有意义唯一的例子
结束
I will answer this question myself, but feel free to provide your answers if you are faster than me or if you don't like my solution. I just came up with this idea and would like to have some opinions on that.
Goal: a configuration class that is readable (like an INI-file) but without having to write (and adapt after a new configuration item has been added) the load and save methods.
I want to create a class like
TMyConfiguration = class (TConfiguration)
...
property ShowFlags : Boolean read FShowFlags write FShowFlags;
property NumFlags : Integer read FNumFlags write FNumFlags;
end;
Calling TMyConfiguration.Save (inherited from TConfiguration) should create a file like
[Options]
ShowFlags=1
NumFlags=42
Question: What is the best way to do this?
This is my proposed solution.
I have a base class
TConfiguration = class
protected
type
TCustomSaveMethod = function (Self : TObject; P : Pointer) : String;
TCustomLoadMethod = procedure (Self : TObject; const Str : String);
public
procedure Save (const FileName : String);
procedure Load (const FileName : String);
end;
The Load methods look like this (Save method accordingly):
procedure TConfiguration.Load (const FileName : String);
const
PropNotFound = '_PROP_NOT_FOUND_';
var
IniFile : TIniFile;
Count : Integer;
List : PPropList;
TypeName, PropName, InputString, MethodName : String;
LoadMethod : TCustomLoadMethod;
begin
IniFile := TIniFile.Create (FileName);
try
Count := GetPropList (Self.ClassInfo, tkProperties, nil) ;
GetMem (List, Count * SizeOf (PPropInfo)) ;
try
GetPropList (Self.ClassInfo, tkProperties, List);
for I := 0 to Count-1 do
begin
TypeName := String (List [I]^.PropType^.Name);
PropName := String (List [I]^.Name);
InputString := IniFile.ReadString ('Options', PropName, PropNotFound);
if (InputString = PropNotFound) then
Continue;
MethodName := 'Load' + TypeName;
LoadMethod := Self.MethodAddress (MethodName);
if not Assigned (LoadMethod) then
raise EConfigLoadError.Create ('No load method for custom type ' + TypeName);
LoadMethod (Self, InputString);
end;
finally
FreeMem (List, Count * SizeOf (PPropInfo));
end;
finally
FreeAndNil (IniFile);
end;
The base class could provide load and save methods for the delphi default types. I can then create a configuration for my application like this:
TMyConfiguration = class (TConfiguration)
...
published
function SaveTObject (P : Pointer) : String;
procedure LoadTObject (const Str : String);
published
property BoolOption : Boolean read FBoolOption write FBoolOption;
property ObjOption : TObject read FObjOption write FObjOption;
end;
Example of a custom save method:
function TMyConfiguration.SaveTObject (P : Pointer) : String;
var
Obj : TObject;
begin
Obj := TObject (P);
Result := Obj.ClassName; // does not make sense; only example;
end;
这篇关于Delphi应用程序配置的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!