轻松实现界面无闪烁多语言切换 万重 2001年 34期 如果你想向海外推广你的软件的话,就必需考虑推出相应的语言版本,虽然Delphi自带多语言包的添加和配置,但是,用这种方法切换语言时界面会出现闪烁,而且实现起来很麻烦。这里我介绍给大家的是利用INI文件来读取界面的语种文字,用这种方法,不但简单易行,而且在切换的时候不会出现界面闪烁。   我们从一个例子出发,看看怎么实现语言的切换。   首先建立一个新工程。放置如下组件:   MainMenu1: TMainMenu;   File1: TMenuItem;   Exit1: TMenuItem;   Label1: TLabel;   Button1: TButton;   CheckBox1: TCheckBox;   CheckBox2: TCheckBox;   Button2: TButton;   Label2: TLabel;   ComboBox1: TComboBox;   Label3: TLabel;   由于要读取INI文件,所以在USES中加入声明IniFiles;然后将Button1和Button2的ShowHint属性设置为True;其中我们用ComboBox1来显示可供选择的语言并进行语言选择。   我们在程序的目录下编辑如下的Chinese GB.Ini文件:   //////////////////////////////   ;翻译的一些规则;   ;翻译前,拷贝 Chinese GB.ini 改名为 yourlanguage.ini   ;仅仅翻译符号“=”后的文字   [Translations]   Label1.Caption=文字1   Label2.Caption=文字2   Label3.Caption=语言   Button1.Caption=按钮1   Button2.Caption=按钮2   Button1.Hint=按钮1_提示   Button2.Hint=按钮2_提示   CheckBox1.Caption=复选框1   CheckBox2.Caption=复选框2   File1.Caption=文件   Exit1.Caption=退出   [Messages]   M1=信息框测试   ////////////////////////////////   同样的方法编辑一个名为English.ini的文件,将“=”左边的文字改为英文。   例如:Label1.Caption=Label1   程序运行时,我们查找当前目录下所有的语言配置文件(*.ini)。为达到这个目的,我们编写如下的函数搜索目录下所有的语言配置文件的文件名,然后将文件名去掉ini扩展名保存在TStrings中返回:   function TForm1.SearchLanguagePack:TStrings;   var   ResultStrings:TStrings;   DosError:integer;   SearchRec:TsearchRec;   begin   ResultStrings:=TStringList.Create;   DosError:=FindFirst(ExtractFilePath(ParamStr(0)+'*.ini',faAnyFile,SearchRec);   while DosError=0 do   begin   { 返回文件名并去掉末尾的.ini字符}   ResultStrings.Add(ChangeFileExt(SearchRec.Name,''));   DosError:=FindNext(SearchRec);   end;   FindClose(SearchRec);   Result:=ResultStrings;   end;   在Form的建立事件中添加代码,将目录下所有的语言文件名加入到选择列表框中。   procedure TForm1.FormCreate(Sender: TObject);   begin   ComboBox1.Items.AddStrings(SearchLanguagePack);   end;   程序的重点在于如何切换语言,我们在ComboBox1的OnChange事件中进行切换操作。这里我写了SetActiveLanguage过程用于实现这一操作。   procedure TForm1.ComboBox1Change(Sender: TObject);   begin   SetActiveLanguage(ComboBox1.Text);   end;   其中SetActiveLanguage代码如下:   procedure TForm1.SetActiveLanguage(LanguageName:string);   const   Translations='Translations';   Messages='Messages';   var   frmComponent:TComponent;   i:Integer;   begin   with TInifile.Create(ExtractFilePath(ParamStr(0)+LanguageName+'.ini') do   begin   for i:=0 to ComponentCount-1 do   { 遍历Form组件 }   begin   frmComponent:=Components[i];   if frmComponent is TLabel then   { 如果组件为TLabel类型则当作TLabel处理,以下同 }   begin   (frmComponent as TLabel).Caption=ReadString(Translations,frmComponent.Name+'.Caption',(frmComponent as TLabel).Caption);   end;   if frmComponent is TCheckBox then   begin   (frmComponent as TCheckBox).Caption:=ReadString(Translations,frmComponent.Name+'.Caption',(frmComponent as TCheckBox).Caption);   end;   if frmComponent is TButton then   begin   (frmComponent as TButton).Caption:=   ReadString(Translations,frmComponent.Name+'.Caption',(frmComponent as TButton).Caption);   (frmComponent as TButton).Hint:=   ReadString(Translations,frmComponent.Name+'.Hint',(frmComponent as TButton.Hint);   end;   if frmComponent is TMenuItem then   begin   (frmComponent as TMenuItem).Caption:=ReadString(Translations,frmComponent.Name+'.Caption',(frmComponent as TMenuItem).Caption);   end;   end;   M1:=ReadString(Messages,'M1',M1;   end;   end;   在这个过程中,我们遍历了Form中的所有组件,根据它们的类别和组件名动态的从ini配置文件中读出应该显示的语言文字。   用遍历组件的方法比一个一个写出具体的组件维护起来要方便很多,代码的适应性也更强。   其中M1为一个字符串变量,这样提示消息也能切换,比如在Button1的Click事件中就可以根据不同的语言给出不同的提示文字。   procedure TForm1.Button1Click(Sender: TObject);   begin   ShowMessage(M1);   end;   好了,整个工程就做完了,你可以运行测试一下,是不是切换迅速而且无闪烁?