项目以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配置文件的更多相关文章

  1. (转载)将DELPHI数据库连接写进INI配置文件中

    将DELPHI数据库连接写进INI配置文件中 procedure TDM.DataModuleCreate(Sender: TObject); var piececonfg:Tinifile; pat ...

  2. C++读写ini配置文件GetPrivateProfileString()&WritePrivateProfileString()

    转载: 1.https://blog.csdn.net/fengbingchun/article/details/6075716 2. 转自:http://hi.baidu.com/andywangc ...

  3. DCMTK开源库的学习笔记4:利用ini配置文件对dcm影像进行归档

    转:http://blog.csdn.net/zssureqh/article/details/8846337 背景介绍: 医学影像PACS工作站的服务端需要对大量的dcm文件进行归档,写入数据库处理 ...

  4. 【个人使用.Net类库】(1)INI配置文件操作类

    开发接口程序时,对于接口程序配置的IP地址.端口等都需要是可配置的,而在Win Api原生实现了INI文件的读写操作,因此只需要调用Win Api中的方法即可操作INI配置文件,关键代码就是如何调用W ...

  5. 【Qt 】QSettings写ini配置文件

    QSettings写ini配置文件(Qt版本5.2): #include "inidemo.h" #include <QSettings> #include <Q ...

  6. c#读写ini配置文件示例

    虽然c#里都是添加app.config 并且访问也很方便 ,有时候还是不习惯用他.那么我们来做个仿C++下的那种ini配置文件读写吧     其他人写的都是调用非托管kernel32.dll.我也用过 ...

  7. vb ——ini 配置文件

    最近在学校VB 开发点小东西, 使用ini配置文件要用到下边连个函数 GetPrivateProfileString (从配置文件得到信息)百度百科的介绍http://baike.baidu.com/ ...

  8. python 提供INI配置文件的操作 ConfigParser

    原文地址:http://www.cnblogs.com/pumaboyd/archive/2008/08/11/1265416.html 红色的为标注信息 +++++++++++++++++引用+++ ...

  9. 第四十二节,configparser特定格式的ini配置文件模块

    configparser用于处理特定格式的文件,其本质上是利用open来操作文件. 特定格式的ini配置文件模块,用于处理ini配置文件,注意:这个ini配置文件,只是ini文件名称的文本文件,不是后 ...

随机推荐

  1. UI5-学习篇-5-SAP创建OData服务-Structure

    本文介绍SAP后端系统基于数据结构创建OData服务过程. 1.创建数据字典 2.创建OData service 2.1创建Gateway service project 事务码:SEGW 点击Cre ...

  2. ncnn 源码学习-Mat.h Mat.c

    纯小白记录下腾讯的ncnn框架源码的学习.纯粹写给自己看的,不保证正确性. Mat 类似于 caffe中的blob,是一个张量的存储结构体. 一.数据成员: 1.void * data 多维数据按一位 ...

  3. 1016B - Segment Occurrences(字符串的匹配)

    题意:字符串a,字符串b,给你q个区间,让你求a的区间内字符串b出现了多少次 之前用的前缀数组做的,没想起来,发现这个其实也可以 #include<cstdio> #include< ...

  4. Python基础-TypeError:takes 2 positional arguments but 3 were given

    Error: 今天写一段简单类定义python代码所遇到报错问题:TypeError: drive() takes 2 positional arguments but 3 were given 代码 ...

  5. ETC2 区别于ETC的重要点

    ETC2 主要是对于NPOT却是4的倍数的贴图有较大压缩,比如一个1920X1080RGB的Loading图,ETC4压缩下不管用,大小5.9M,ETC2下压缩为1M

  6. php中的错误和异常

    总结: php错误不会抛出异常,因此不能被catch,但会根据配置写入日志文件或者输出到浏览器,所以可以通过日志文件查看错误 php异常都必须自己抛出,并通过catch捕捉.SQL语句执行的错误好像可 ...

  7. 减少mysql主从数据同步延迟

    网上给出的解决办法: 基于局域网的master/slave机制在通常情况下已经可以满足'实时'备份的要求了.如果延迟比较大,就先确认以下几个因素:1. 网络延迟2. master负载3. slave负 ...

  8. uml用例关系

    关联关系 关联关系是指执行者与用例之间的关系,又称为通信关系,如果某个执行者可以对某个用例进行操作,它们之间就具有关联关系,如下图所示,“经理”有一个功能为“查看库存报表”,因此可以在执行者“经理”和 ...

  9. cin输入bug

    我们先来谈谈cin.clear的作用,第一次看到这东西,很多人以为就是清空cin里面的数据流,而实际上却与此相差很远,首先我们看看以下代码: #include <iostream> usi ...

  10. java 中 Integer 传参方式的问题

    Java本身都是值传递式的调用,对于对象传递的是地址值.给地址值重新赋值等于重新指向,不会影响外层. 而且这里Integer对象也有特殊性.其实现上可能类似 class Integer{ final ...