Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > Delphi > 利用INI文件实现界面无闪烁多语言切换(DELPHI)
【标  题】:利用INI文件实现界面无闪烁多语言切换(DELPHI)
【关键字】:文件,语言,INI,多语言,闪烁,DELPHI,IN,INI,DELPHI
【来  源】:网络

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

Your Ad Here 一、引言

越来越多的程序使用了多国语言切换,虽然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在运行期,获取组件的相应属性,并进行动态设置,达到多语言切换功能。

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

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;

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编程中运行时类型信息的应用技巧,同时掌握如何在程序运行时动态创建菜单。

在Delphi中用ADSI创建IIS的虚拟目录:【上一篇】
在Delphi 7 中用Indy开发Socket应用程序:【下一篇】
【相关文章】
没有相关文章
【随机文章】
  • Javascript制作网页对联
  • Xwindow读书笔记
  • 数据可视化表示问题
  • ldd3笔记_4_模块VS应用程序
  • 自己动手,下载NASA的卫星图片Blue Marble。
  • 用Fireworks制作水波效果
  • 看《JAVA算法》有感~!
  • Java: JNI完全手册
  • JavaScript的方法技巧和使用
  • 加密你的Access数据库
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.