delphi读取ini文件 

INI文件在系统配置及应用程序参数保存与设置方面,具有很重要的作用,所以

可视化的编程一族,如VB、VC、VFP、Delphi等都提供了读写INI文件的方法,其

中Delphi中操作INI文件,最为简洁,这是因为Delphi提供了一个TInifile类,

使我们可以非常灵活的处理INI文件

 

首先,要获得当前文件目录、文件名,有三个Delphi自带的函数。

  1. ExtractFilePath  //路径后面带有 "/"  (不管是在磁盘根目录还是哪里)   
  2. ExtractFileName  //文件名   
  3. ExtractFileExt   //扩展名  

例子:

  1. ExtractFilePath(ParamStr(0));  // C:/   
  2. ExtractFileName(ParamStr(0));  // Project.exe   
  3. ExtractFileExt(ParamStr(0));   // .exe  

关于ini格式:

INI文件的格式很简单,最基本的三个要素是:parameters,sections和comments。

什么是parameters?

INI所包含的最基本的“元素”就是parameter;每一个parameter都有一个name和一个value,name和value是由等号“=”隔开。name在等号的左边。

如:

      name = value

什么是sections ?

所有的parameters都是以sections为单位结合在一起的。所有的section名称都是独占一行,并且sections名字都被方括号包围着([ and ])。在section声明后的所有parameters都是属于该section。对于一个section没有明显的结束标志符,一个section的开始就是上一个section的结束,或者是end of the file。Sections一般情况下不能被nested,当然特殊情况下也可以实现sections的嵌套。

section如下所示:

[section]

什么是comments ?

在INI文件中注释语句是以分号“;”开始的。所有的所有的注释语句不管多长都是独占一行直到结束的。在分号和行结束符之间的所有内容都是被忽略的。

注释实例如下:

;comments text

当然,上面讲的都是最经典的INI文件格式,随着使用的需求INI文件的格式也出现了很多变种;

INI实例:

; last modified 1 April 2001 by John Doe  
[owner]  
name=John Doe  
organization=Acme Products     
[database]  server=192.0.2.42     
; use IP address in case network name resolution is not working  port=143  file = "acme payroll.dat"  

1、在Interface的Uses节增加IniFiles;

2、在Var变量定义部分增加一行: myinifile:Tinifile;

定义类的一个实例。然后,就可以对变量myinifile进行创建、打开、读取、写入等操作了。

三、打开INI文件

myinifile:=Tinifile.create(program.ini);

上面这一行语句将会为变量myinifile与具体的文件program.ini建立联系,然后,就可以通过变量myinifile,来读写program.ini文件中的关键字的值了。
值得注意的是,如果括号中的文件名没有指明路径的话,那么这个Program.ini文件会存储在Windows目录中,把Program.ini文件存储在应用程序当前目录中的方法是:为其指定完整的路径及文件名。下面的两条语句可以完成这个功能:
Filename:=ExtractFilePath(Paramstr
(0))+program.ini;
myinifile:=Tinifile.Create(filename);

五、写入INI文件

同样的,TInifile类也提供了三种不同的对象方法,向INI文件写入字符串、整型数及布尔类型的关键字。
myinifile.writestring(小节名,关键字,变量或字符串值);
myinifile.writeinteger(小节名,关键字,变量或整型数值);
myinifile.writebool(小节名,关键字,变量或True或False);
当这个INI文件不存在时,上面的语句还会自动创建该INI文件。

六、删除关键字

除了可用写入方法增加一个关键字,Tinifile类还提供了一个删除关键字的对象方法:
myinifile.DeleteKey(小节名,关键字);

七、小节操作

增加一个小节可用写入的方法来完成,删除一个小节可用下面的对象方法:
myinifile.EraseSection(小节名);
另外Tinifile类还提供了三种对象方法来对小节进行操作:
myinifile.readsection(小节名,TStrings变量);可将指定小节中的所有关键字名读取至一个字符串列表变量中;
myinifile.readsections(TStrings变量);可将INI文件中所有小节名读取至一个字符串列表变量中去。
myinifile.readsectionvalues(小节名,TStrings变量);可将INI文件中指定小节的所有行(包括关键字、=、值)读取至一个字符串列表变量中去。

八、释放

在适当的位置用下面的语句释放myinifile:

myinifile.distory;

下面是具体例子。源代码如下。创建了一个myini.ini文件,有一个名为 newini的小节,有3个关键字“用户名称”“已运行时间”“是否正式用户”。运行效果,可以在edit1里边填入“用户名称”;edit2显示时间, 不可以改变数值;checkbox1通过打勾,保存时间和“用户名称”进入myini.ini文件里边,重新打开应用程序时,显示的时保存下来的时间和填 入的“用户名称”,如果在myini.ini文件里边修改,效果和在程序运行过程中修改时一样的。

实例:

 

  1. function TForm1.Autoclick(url, urlt: string): Boolean; 
  2. var 
  3.   htp:tidhttp; 
  4.   myini:tinifile; 
  5.   inifile:string; 
  6.   openurl,openurl2:string; 
  7. begin 
  8.   htp:=tidhttp.Create(nil); 
  9.   inifile:=ExtractFilePath(paramstr(0))+'Config.ini'
  10.   myini:=Tinifile.Create(inifile); 
  11. // myini:=Tinifile.Create(ExtractFilePath(paramstr(0))+'Config.ini'); 也可以一句话写成这句
  12.   try 
  13.     htp.Request.Referer:=myini.ReadString('Config','Referer',''); 
  14.     htp.Request.Host:=myini.ReadString('Config','host',''); 
  15.     showmessage(htp.Request.Referer); 
  16.   openurl:=myini.ReadString('Config','url',''); 
  17.     if openurl<>'' then 
  18.      htp.get(openurl); 
  19.     finally 
  20.       htp.Free
  21.       myini.Free
  22.       end
  23. end
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,inifiles, StdCtrls, ExtCtrls;
  {调用inifiles 类}
type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Edit1: TEdit;
    Edit2: TEdit;
    Timer1: TTimer;
    CheckBox1: TCheckBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
var
myinifile:TInifile;
{定义一个类的实例}
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
filename:string; 
begin
{下面两行的书写形式,在应用程序的路径下创建ini文件}
filename:=ExtractFilePath(paramstr(0))+myini.ini;
myinifile:=TInifile.Create(filename);
edit1.Text:=myinifile.ReadString(newini,用户名称,胡长浩);
edit2.text:=inttostr(myinifile.readinteger
(newini,已运行时间,0));
checkbox1.Checked:=myinifile.readbool
(newini,是否正式用户,False);
 {newini是小节名字,中间字段是关键字的名字,第三个字段是缺省值。当myini.ini不存在时,上面的语句自动创建这个文件,上边几行里的引号是单引号}
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
myinifile.writestring(newini,用户名称,edit1.Text);
myinifile.writeinteger(newini,已运行时间,
strtoint(edit2.text));
myinifile.writebool(newini,是否正式用户,
checkbox1.Checked);
myinifile.Destroy;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  edit2.Text:=inttostr(strtoint(edit2.text)+1);
end;
end.

利用INI文件实现界面无闪烁多语言切换

熊斌 landragon@tom.com

一、引言

越来越多的程序使用了多国语言切换,虽然DELPHI自带多语言包的添加和配置,

但是那种方法在切换语言时界面会出现闪烁,而且实现起来很麻烦,这里我介绍

给大家的是利用INI文件来读取界面的语种文字,用这种方法,不但简单易行,

而且在切换的时候不会出现界面的闪烁。

二、InI文件格式说明

1、语种定义

[Language] //语言

DefaultLang = ChineseGB //界面的默认语种(InI文件名,不带扩展名)

Language = 语种 //菜单标题

ChineseGB = 简体中文 //相应语种文件名

ChineseBig = 繁体中文

English = 英文

⑴ 如果DefaultLang项没有设置,则为语种目录中所寻找到的InI的第一个文件

,做为当前界面语种,所有Ini文件都要设置成一样;

⑵ Language为菜单界面上所显示的标题,不设置时,默认为‘Language’;

⑶ 如果Language以下项没有设置,则相应语种的菜单标题为文件名(不带扩展

名)。

2、窗体界面定义

[FormName] //需要变换的窗口

.Caption = 演示窗体 //本窗口的属性,表示为:[窗口名].属性名 = 语言

Button1.Hint = 按钮说明 //控件的属性,表示为:控件名.属性名 = 语言

ComboBox1.Items = 简体中文||英文 //其中“||”为分隔符

注:⑴ 在InI文件中每行“//”开始的说明文字不要输入;

⑵ 对继承自TStrings的属性,其各个项目之间需用“||”分隔;

⑶ 设计思想来源于KeyZhang所编写的《多语言切换函数 For Delphi》组件。

三、实现原理

RTTI的基本设计思想是在运行时访问给定数据类型的信息,该类型可以是类也可

以是简单的Pascal数据类型(int、string、char等)。本文便是通过RTTI在运

行期,获取组件的相应属性,并进行动态设置,达到多语言切换功能。


利用INI文件实现界面无闪烁多语言切换

熊斌 landragon@tom.com

四、各个函数的定义及实现

1、程序运行时,我们查找语种目录下所有的语言配置文件(*.ini),为了达到

这个目的,我编写了如下的函数搜索目录下所有的语言配置文件的文件名,然后

将文件名去掉ini扩展名保存返回:

procedure SearchLanguagePack (lngStrings: TStrings);

var

DosError: Integer;

SearchRec: TsearchRec;

begin

DosError := FindFirst (ExtractFilePath (ParamStr (0))

'Language\*.ini', faAnyFile, SearchRec);

while DosError = 0 do

begin

{ 返回的文件名并去掉末尾的.ini字符 }

lngStrings.Add (ChangeFileExt (SearchRec.Name, ''));

DosError := FindNext (SearchRec);

end;

FindClose(SearchRec);

end;

2、实现界面的多语言切换函数:

function ChangeLanguage (Form: TForm; Lngfile: string): Boolean;

var

INIF: TIniFile; //InI文件

SL: TStringList; // InI文件中读出的相应窗体的信息

TmpSL: TStringList; //将每一行信息,以“=”分隔的信息

Key: string; //“=”左边的信息

Value: string; //“=”右边的信息

CompName: string; //组件名

CompProp: string; //组件属性名

I: Integer;

AComponent: TComponent; //相应组件


procedure Split (S: string; SplitChar: string; R: TStrings); //将字符

串分隔

var

P, L, C: Integer;

begin

R.Clear;

L := Length (S);

//确定分隔符的长度,以便删除字符串中的相应字符

C := Length (SplitChar);

//循环分隔字符串

repeat

P := Pos (SplitChar, S);

//如果在字符串中没有找到分隔符,说明为最后一个

if P = 0 then C := 1;

R.Add (Copy (S, P C, L));

Delete(S, P, L);

until P = 0;

end;


//设置相应属性值

procedure SetPropertyValue (AComponent: TComponent; sProperty, sValue:

string);

var

PropInfo: PPropInfo;

AStrings: TStringList;

begin

if AComponent <> nil then

begin

PropInfo := GetPropInfo(AComponent, sProperty);

if PropInfo <> nil then

begin

case PropInfo.PropType^.Kind of

tkString, tkLString: //字符串属性

SetStrProp(AComponent, PropInfo, sValue);

tkInteger: //序数属性

SetOrdProp(AComponent, PropInfo, StrToInt(sValue));

else

if PropInfo.PropType^.Name = 'TStrings' then //列表属性

begin

AStrings := TStringList.Create;

try

Split (sValue, '||', AStrings);

SetOrdProp (AComponent, PropInfo, Integer (AStrings));

finally

AStrings.Free;

end; // end try

end; // end if PropInfo.PropType^.Name = 'TStrings'

end; // end case

end; // end if PropInfo <> nil

end; // end if AComponent <> ni

end;


begin

Result := True;

SL := TStringList.Create;

try

INIF := TIniFile.Create (LngFile); // 打开语种初始化文件

try

INIF.ReadSectionValues (Form.Name, SL); // 读取相应窗体信息

finally

INIF.Free;

end;

TmpSL := TStringList.Create;

try

for I := 0 to SL.Count - 1 do // 分隔每一行信息

begin

Split (SL.Strings[I], '=', TmpSL);

Key := Trim (TmpSL.Strings[1]);

CompName := Trim (Copy(Key, 1, Pos ('.', Key) - 1));

if CompName = '' then // 确定组件

AComponent := Form

else

AComponent := Form.FindComponent (CompName);

CompProp := Trim (Copy (Key, Pos ('.', Key) 1, Length (Key)));

Value := Trim (TmpSL.Strings[0]);

SetPropertyValue (AComponent, CompProp, Value); // 设置属性

end;

finally

TmpSL.Free;

end;

finally

SL.Free;

end;

end;


利用INI文件实现界面无闪烁多语言切换

熊斌 landragon@tom.com

3、在Form显示的事件中添加代码,将目录下所有的语言文件名加入菜单项:

procedure TForm1.FormShow(Sender: TObject);

var

lngStrings, tmpStrings: TStrings;

I: Integer;

lngMenu: TMenuItem;

Filename: string;

IniF: TIniFile;

begin

lngStrings := TString.Create;

try

SearchLanguagePack (lngStrings); // 查找语种文件

if lngStrings.Count = 0 then // 没有找到语种文件直接退出

exit;

Filename := ExtractFilePath (ParamStr (0)) 'Language\'

lngStrings.Strings[0] '.ini';

IniF := TIniFile.Create (Filename);

Filename := IniF.ReadString('Language', ' DefaultLang ', '');// 设置为

默认语种

if Filename <> '' then

begin

Filename := ExtractFilePath (ParamStr (0)) 'Language\' Filename

'.ini';

if FileExists (Filename) then

begin

IniF.Free;

IniF := TIniFile.Create (Filename);

end;

end;

lngMenu := TMenuItem.Create (self);

lngMenu.Name := 'Language';

lngMenu.Caption := IniF.ReadString('Language', 'Language',

'Language');

MainMenu1.Items[MainMenu1.Items. Count].Add (lngMenu); // 语种菜单放到

主菜单的最后

tmpStrings := TString.Create;

try

for I := 0 to lngStrings.Count – 1 do // 动态创建菜单项

begin

lngMenu := TMenuItem.Create (self);

lngMenu.Name := lngStrings.Strings[I]; // 将菜单项的名称赋予文件名

lngMenu.Caption := IniF.ReadString('Language', lngStrings.Strings[I],

lngStrings.Strings[I]');

lngMenu.onClick := lngMenuClick; // 菜单事件

Language.Insert (Language.Items.Count, lngMenu); // 添加到语种菜单的最

后一项上

end;

finally

tmpStrings.Free;

end;

finally

lngStrings.Free;

end;

ChangeLanguage (Form1, IniF); // 改变界面语种

IniF.Free;

end;

4、窗体中语种菜单的事件响应:

procedure TForm1.lngMenuClick (Sender: TObject);

var

Filename: string;

begin

if Sender is TMenuItem then

begin

// 确定语种文件,菜单项名称为语种文件名

Filename := ExtractFilePath (ParamStr (0)) 'Language\' (Sender as

TMenuItem).Name '.ini';

ChangeLanguage (Form1, Filename);

end;

end;

五、结束语

通过本次学习,让读者初步了解Delphi编程中运行时类型信息的应用技巧,同时

掌握如何在程序运行时动态创建菜单。

实例说明:

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, ComCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdExplicitTLSClientServerBase, IdFTP, StdCtrls,Inifiles;


procedure TForm1.oncreate(Sender: TObject);
begin

myini:=Tinifile.Create(ExtractFilePath(paramstr(0))+'config.ini');
idftp1.Host:=myini.ReadString('FTP','host','');
//showmessage(idftp1.host);
idftp1.Username:=myini.ReadString('FTP','username','');
idftp1.Password:=myini.ReadString('FTP','password','');
myini.Free;
end;

//读取INI文件

INI文件内容

[FTP]

host=

usename=

password=