Delphi: RTTI与ini配置文件
项目以Rtti特性做文件参数配置,简化每项读写ini操作,记录以做备忘,代码如下:
unit uGlobal; interface uses
Windows, Messages, SysUtils, Variants, Classes, Forms, TypInfo, IniFiles; type
TConfigBase = class(TPersistent)
private
FFileName: string;
procedure Load(AIniFile: TIniFile); overload;
procedure Save(AIniFile: TIniFile); overload;
protected
function GetSectionName: string; virtual;
procedure LoadProperty(PropInfo: PPropInfo; const Section: string; IniFile: TIniFile); virtual;
procedure SaveProperty(PropInfo: PPropInfo; const Section: string; IniFile: TIniFile); virtual;
public
procedure Load(AFileName: string); overload;
procedure Save(AFileName: string); overload;
end; TLiveUpdate = class; TApp = class(TConfigBase)
private
FAppName: string;
FVersion: string;
FShowMsg: Boolean;
FProductID: Integer;
FWindowState: TWindowState;
FLiveUpdate: TLiveUpdate;
protected
function GetSectionName: string; override;
public
constructor Create;
destructor Destroy; override;
published
property AppName: string read FAppName write FAppName;
property Version: string read FVersion write FVersion;
property ShowMsg: Boolean read FShowMsg write FShowMsg;
property ProductID: Integer read FProductID write FProductID;
property WindowState: TWindowState read FWindowState write FWindowState;
property LiveUpdate: TLiveUpdate read FLiveUpdate write FLiveUpdate;
end; TLiveUpdate = class(TConfigBase)
private
FAvailabled: Boolean;
FAutoUpdate: Boolean;
FUpdatePeriod: Integer;
FLastUpdateDate: TDateTime;
protected
procedure LoadProperty(PropInfo: PPropInfo; const Section: string; IniFile: TIniFile); override;
procedure SaveProperty(PropInfo: PPropInfo; const Section: string; IniFile: TIniFile); override;
public
constructor Create;
published
property Availabled: Boolean read FAvailabled write FAvailabled;
property AutoUpdate: Boolean read FAutoUpdate write FAutoUpdate;
property UpdatePeriod: Integer read FUpdatePeriod write FUpdatePeriod;
property LastUpdateDate: TDateTime read FLastUpdateDate write FLastUpdateDate;
end; function App: TApp; implementation var
FApp: TApp; function App: TApp;
begin
if FApp = nil then
FApp := TApp.Create;
Result := FApp;
end; { TConfigBase } function TConfigBase.GetSectionName: string;
begin
Result := ClassName;
if Result[] = 'T' then
Result := Copy(Result, , Length(Result) - );
end; procedure TConfigBase.Load(AFileName: string);
var
IniFile: TIniFile;
begin
if not FileExists(AFileName) then Exit; IniFile := TIniFile.Create(AFileName);
try
Load(IniFile);
finally
IniFile.Free;
end;
end; procedure TConfigBase.Load(AIniFile: TIniFile);
var
I, Count: Integer;
PropInfo: PPropInfo;
PropList: PPropList;
Section: string;
begin
Count := GetTypeData(ClassInfo)^.PropCount;
if Count = then Exit; GetMem(PropList, Count * SizeOf(Pointer));
try
Section := GetSectionName;
GetPropInfos(ClassInfo, PropList);
for I := to Count - do
begin
PropInfo := PropList^[I];
if (PropInfo <> nil) and IsStoredProp(self, PropInfo) and (PropInfo^.SetProc <> nil) then
LoadProperty(PropInfo, Section, AIniFile);
end;
finally
FreeMem(PropList);
end;
end; procedure TConfigBase.LoadProperty(PropInfo: PPropInfo; const Section: string;
IniFile: TIniFile);
var
PropType: PTypeInfo;
Obj: TObject;
begin
PropType := PropInfo^.PropType^;
if (PropType^.Kind <> tkClass) and (not IniFile.ValueExists(Section, string(PropInfo^.Name))) then Exit; case PropType^.Kind of
tkClass:
begin
Obj := GetObjectProp(self, PropInfo);
if Assigned(Obj) and (Obj is TConfigBase) then
TConfigBase(Obj).Load(IniFile);
end;
tkInteger, tkChar, tkWChar:
SetOrdProp(Self, PropInfo, IniFile.ReadInteger(Section, string(PropInfo.Name), PropInfo^.Default));
tkString, tkLString, tkUstring, tkWString:
SetStrProp(Self, PropInfo, IniFile.ReadString(Section, string(PropInfo.Name), ''));
tkEnumeration:
SetEnumProp(Self, PropInfo, IniFile.ReadString(Section, string(PropInfo.Name), ''));
tkSet:
SetSetProp(Self, PropInfo, IniFile.ReadString(Section, string(PropInfo.Name), ''));
tkFloat:
SetFloatProp(Self, PropInfo, IniFile.ReadFloat(Section, string(PropInfo^.Name), ));
end;
end; procedure TConfigBase.Save(AFileName: string);
var
IniFile: TIniFile;
begin
if AFileName = '' then Exit; IniFile := TIniFile.Create(AFileName);
try
try
Save(IniFile);
except on E: Exception do
OutputDebugString(PChar(Format('Exceptoin: save to file %s fail, err: %s', [AFileName, E.Message])));
end;
finally
IniFile.Free;
end;
end; procedure TConfigBase.Save(AIniFile: TIniFile);
var
I, Count: Integer;
PropInfo: PPropInfo;
PropList: PPropList;
Section: string;
begin
Section := GetSectionName;
Count := GetTypeData(ClassInfo)^.PropCount;
if Count > then
begin
GetMem(PropList, Count * SizeOf(Pointer));
try
GetPropInfos(ClassInfo, PropList);
for I := to Count - do
begin
PropInfo := PropList^[I];
if (PropInfo <> nil) and IsStoredProp(self, PropInfo) and (PropInfo^.GetProc <> nil) then
SaveProperty(PropInfo, Section, AIniFile);
end;
finally
FreeMem(PropList);
end;
end;
end; procedure TConfigBase.SaveProperty(PropInfo: PPropInfo; const Section: string;
IniFile: TIniFile);
var
PropType: PTypeInfo;
Obj: TObject;
const
Format_d = '%d';
begin
PropType := PropInfo^.PropType^;
case PropType^.Kind of
tkClass:
begin
Obj := GetObjectProp(self, PropInfo);
if Assigned(Obj) and (Obj is TConfigBase) then
TConfigBase(Obj).Save(IniFile);
end;
tkInteger, tkChar, tkWChar:
IniFile.WriteInteger(Section, string(PropInfo^.Name), GetOrdProp(Self, PropInfo));
tkString, tkLString, tkUstring, tkWString:
IniFile.WriteString(Section, string(PropInfo^.Name), GetWideStrProp(Self, PropInfo));
tkEnumeration:
IniFile.WriteString(Section, string(PropInfo^.Name), GetEnumName(PropType, GetOrdProp(Self, PropInfo)));
tkSet:
IniFile.WriteString(Section, string(PropInfo^.Name), GetSetProp(Self, PropInfo));
tkFloat:
IniFile.WriteFloat(Section, string(PropInfo^.Name), GetFloatProp(Self, PropInfo));
end;
end; { TApp } constructor TApp.Create;
begin
FFileName := ChangeFileExt(ParamStr(), '.ini');
FWindowState := wsNormal;
FLiveUpdate := TLiveUpdate.Create;
Load(FFileName);
end; destructor TApp.Destroy;
begin
Save(FFileName);
inherited Destroy;
end; function TApp.GetSectionName: string;
begin
Result := 'System';
end; { TLiveUpdate } constructor TLiveUpdate.Create;
begin
FAvailabled := True;
FAutoUpdate := True;
FUpdatePeriod := ;
FLastUpdateDate := Now;
end; procedure TLiveUpdate.LoadProperty(PropInfo: PPropInfo; const Section: string;
IniFile: TIniFile);
begin
if PropInfo^.Name = 'LastUpdateDate' then
FLastUpdateDate := IniFile.ReadDateTime(Section, string(PropInfo^.Name), Now)
else
inherited;
end; procedure TLiveUpdate.SaveProperty(PropInfo: PPropInfo; const Section: string;
IniFile: TIniFile);
begin
if PropInfo^.Name = 'LastUpdateDate' then
IniFile.WriteDateTime(Section, string(PropInfo^.Name), GetFloatProp(Self, PropInfo))
else
inherited;
end; end.
使用方法:
procedure TForm1.FormCreate(Sender: TObject);
begin
App.AppName := 'RttInfo';
App.Version := GetFileVersion(ParamStr());
end; procedure TForm1.FormDestroy(Sender: TObject);
begin
App.Free;
end;
比单个字段读写ini字段,省事
Delphi: RTTI与ini配置文件的更多相关文章
- (转载)将DELPHI数据库连接写进INI配置文件中
将DELPHI数据库连接写进INI配置文件中 procedure TDM.DataModuleCreate(Sender: TObject); var piececonfg:Tinifile; pat ...
- C++读写ini配置文件GetPrivateProfileString()&WritePrivateProfileString()
转载: 1.https://blog.csdn.net/fengbingchun/article/details/6075716 2. 转自:http://hi.baidu.com/andywangc ...
- DCMTK开源库的学习笔记4:利用ini配置文件对dcm影像进行归档
转:http://blog.csdn.net/zssureqh/article/details/8846337 背景介绍: 医学影像PACS工作站的服务端需要对大量的dcm文件进行归档,写入数据库处理 ...
- 【个人使用.Net类库】(1)INI配置文件操作类
开发接口程序时,对于接口程序配置的IP地址.端口等都需要是可配置的,而在Win Api原生实现了INI文件的读写操作,因此只需要调用Win Api中的方法即可操作INI配置文件,关键代码就是如何调用W ...
- 【Qt 】QSettings写ini配置文件
QSettings写ini配置文件(Qt版本5.2): #include "inidemo.h" #include <QSettings> #include <Q ...
- c#读写ini配置文件示例
虽然c#里都是添加app.config 并且访问也很方便 ,有时候还是不习惯用他.那么我们来做个仿C++下的那种ini配置文件读写吧 其他人写的都是调用非托管kernel32.dll.我也用过 ...
- vb ——ini 配置文件
最近在学校VB 开发点小东西, 使用ini配置文件要用到下边连个函数 GetPrivateProfileString (从配置文件得到信息)百度百科的介绍http://baike.baidu.com/ ...
- python 提供INI配置文件的操作 ConfigParser
原文地址:http://www.cnblogs.com/pumaboyd/archive/2008/08/11/1265416.html 红色的为标注信息 +++++++++++++++++引用+++ ...
- 第四十二节,configparser特定格式的ini配置文件模块
configparser用于处理特定格式的文件,其本质上是利用open来操作文件. 特定格式的ini配置文件模块,用于处理ini配置文件,注意:这个ini配置文件,只是ini文件名称的文本文件,不是后 ...
随机推荐
- 07_组件三大属性(1)_state
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 我要重新开始学习C++了!
C++实在是博大精深!之前总不想读厚厚的C++ Primer. 然而,现在的水平真的只是初学者!只是因为写的代码太简单,所以没有用到一些特性.可以说还是门外汉! 写笔记!
- git使用 从远程库克隆和更新到本地
从远程库克隆到本地. git clone git@github.com:kingbook/Framework.git 或 git clone http://github.com/kingBook/Fr ...
- ReactiveX 学习笔记(16)RxPY
RxPY RxPY 是 ReactiveX 的 Python语言实现. # 安装 RxPY $ pip3 install rx Successfully installed rx-1.6.1 Basi ...
- Linux Install redis
1.将下载好的压缩包放到/usr/local目录下# tar xzf redis-3.0.2.tar.gz # cd redis-3.0.2 # make//--------------------- ...
- MTIM(中间人攻击)
所谓的MITM攻击就是通过拦截正常的网络通信数据,并进行数据篡改和嗅探,而通信的双方却毫不知情. 信息篡改 当主机A.和主机B通信时,都由主机C来为其“转发”,如图一,而A.B之间并没有真正意思上的直 ...
- avalon2学习教程05属性操作
avalon2与avalon1的属性操作虽然都是使用ms-attr,但用法完全不一样. avalon1是这样操作属性的 其语法为 ms-attr-valueName="vmProp" ...
- 基于Java SE集合的图书管理系统
图书管理系统一.需求说明1.功能:登录,注册,忘记密码,管理员管理,图书管理.2.管理员管理:管理员的增删改查.3.图书管理:图书的增删改查.4.管理员属性包括:id,姓名,性别,年龄,家庭住址,手机 ...
- canvas入门笔记
1.Canvas的使用注意 A.要在页面中添加一对canvas标记,默认占300*150的区域 B.我们可以通过html属性‘width’,‘height’来设置canvas的宽高,不可以通过cs ...
- python基础学习Day11 函数名的应用、闭包、迭代器
一.函数名的应用 1.函数名就是函数的内存地址 def func(): print(666) func() print(func) #函数的内存地址 2.函数名可以作为变量 def func1(): ...