中英文切换问题(50分)

  • 主题发起人 主题发起人 jiang_yun_2005
  • 开始时间 开始时间
J

jiang_yun_2005

Unregistered / Unconfirmed
GUEST, unregistred user!
有什么好的办法能作到多国语言切换呢?
我定义了几个XML文件分别对常用的英文翻译成中、日、德
三国语言
现在想对以前的老程序,全英文的,主要是所有的控件有caption属性的想
根据选择来自动切换语言,怎么做呢?
我有一个笨办法:
在窗体onshow的时候,搜寻所有的控件,如果的Tlable类的,我取它的caption用XML文件定义的去匹配然后修改;
如果控件的showhint等于TRUE的把hint拿出来匹配。。。好象不是太好
有什么好的办法吗?
 
话题1840475的标题是: delphi中怎样动态实现多国语言支持.在线等待!!! (100分)
分类:系统相关 20020509 (2003-05-08 15:04:00)
delphi中怎样动态实现多国语言支持.具体实现方法.

cee (2003-05-08 16:23:00)
http://www.beeship.com/onedocs.asp?id=5

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

作者: 万重
Tuesday, September 24 2002 12:33 PM
越来越多的程序使用了多国语言切换,虽然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扩展名保存返回:
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;
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;
就可以根据不同的语言给出不同的提示文字。

好了,整个工程就做完了,你可以运行测试一下,是不是切换迅速而且无闪烁。

cee (2003-05-08 16:34:00)
http://tech.enet.com.cn/document/20010317/2001031717303201.shtml

编写支持多国语言的程序

2001/03/17 17:30 作者:rssw CHINAASP



曾经有人问怎样编写支持多国语言的程序, 让它能够根据所运行的操作系统自动显示相应的文字。 而且不但要替换Windows标准对话框, 还要自动替换窗口标题、 按钮标题等所有显示的文字和所有错误提示。


我想使用Delphi 5的Integrated Translation Environment (ITE)可以轻易得完成这个工作。


我们创建一个示意性的工程MultiLanguage, 在Form上放一个Label和一个Button, 分别把Caption赋值为“English Label” 和“English Button”。


选择菜单Project|anguages|Add ..., Delphi显示Add Languages对话框, 选择Next。


从语言列表中选中“英语(美国)” 和“中文(中国)”, 选择Next。


ITE会根据所选的语言创建子目录,目录名称是语言的缩写,选择Next。


第一次增加语言时, Update Mode | Create new, 选择Next。


选择Finish。


Delphi会自动创建支持不同语言的资源动态库。


Delphi还会自动创建一个工程组, 其中包括原有的MultiLanguages.EXE, 还包括新建的两个资源动态库 (MultiLanguages.enu, MultiLanguages.chs)。 保存工程组。


Delphi启动Translation Manager, 左边是需要翻译的语言, 右边是完成百分比。


选择“中文(中国)”|Forms|Unit1, 在右边第15行和20行填写翻译后的中文。 保存并关闭。


打开Project Manager, 编译MultiLanguages.enu和MultiLanguages.chs, Delphi会在相应的子目录生成资源动态库, 但后缀不是DLL而是ENU和CHS。



antic_ant (2003-05-08 16:37:00)
转自大富翁
多国语言之step


把Demos/Richedit/reinit.pas往自己project目录一拷,在
project中又把它加了进来

设置一下需要的语言页常数。
implementation

uses reinit;

const
ENGLISH = (SUBLANG_ENGLISH_US shl 10) or LANG_ENGLISH;
CHINESE = (SUBLANG_CHINESE_SIMPLIFIED shl 10) or LANG_CHINESE;

{$R *.DFM}

做个初始化
procedure TForm1.FormCreate(Sender: TObject);
begin
mnuEnglish.Tag:=ENGLISH;
mnuChinese.Tag:=CHINESE;
end;



于是把两了菜单都指到了一个地方
procedure TForm1.mnuLangClick(Sender: TObject);
begin
if LoadNewResourceModule(TComponent(Sender).Tag) <> 0 then
ReinitializeForms;
end;

菜单[Project]-[Languages]-[Add...]
[Next>],选择中文(chs),英语(eng);(我只用了这两种语言);
[Next>],[Next>],[Next>],[Finsih],[Yes]
让你保存dpg时小心目录可能是chs,应该用上一级目录才好。

看到了吗,这是你可以修改所有的东西。
现在可以看到你的project Manager中有3个项目,project1.exe,porject1.eng,project1.chs
后面两了是资源文件,你可以
1,双击project1.eng -- form1,然后修改一些东西。比如button1的caption="eng";改变一下它
的大小和字体。
2,双击project1.chs -- form1,然后修改一些东西。比如button1的caption="chs";改一下字体。
不过最好不要随意改动form的大小和位置!
选中project1.exe,设定为Activate;


右键project1.chs--build;
右键project1.eng--build;
右键project1.exe--build;
run

噫,你会发现exe中的界面不起作用了。呵呵,系统自己自动选择了一个语言页嘛。
什么你不要自动,
对了如果要在调出那个grid方式修改的工具可以[view]-[Translation Manager];



hryyx (2003-05-08 16:37:00)
C:/Program Files/Borland/Delphi6/Demos/RichEdit

诸葛白痴 (2003-05-08 16:49:00)
我已用ini和控件的Caption做了一个类出来了,你要的话可以留个E_Mail,我在寻求最
佳用unicode的方法,但是目前没有一点线索:(

vmao (2003-05-08 17:07:00)
我也要:
vmao@163.com

20020509 (2003-05-08 17:13:00)
xinhai@88ip.com
谢谢你了.


david1976 (2003-06-01 16:41:00)
我也要:
谢谢了wei1030@21cn.com

Lamb (2003-06-02 14:47:00)
delphi自带的工具太初级,而且提示信息等代码中涉及到语言的内容还需要单独写东西来判断和显示不同的语言。
最好还是利用2000/XP本身的多语言特性来制作独立的不同语言版本,这样也便于管理。

20020509 (2003-07-07 10:07:00)
多人接受答案了。


antic_ant-30,cee-50,诸葛白痴-20,的回答最终被接受。
 
话题2283155的标题是: 如何象flashget那样利用ini文件实现多国语言程序。 (100分)
分类:IDE/使用技巧 mumu (2003-11-10 7:08:00)
最好有具体的demo。borland.delphi.demo中的多国语言不方便:(

LLYDHL (2003-11-10 16:42:00)
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants,inifiles, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
RBEnglish: TRadioButton;
RBTw: TRadioButton;
ComboBox1: TComboBox;
Button1: TButton;
Label1: TLabel;
procedure RBEnglishClick(Sender: TObject);
procedure RBTwClick(Sender: TObject);
procedure ComboBox1Change(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
Myini:TiniFile;
implementation

{$R *.dfm}

procedure TForm1.RBEnglishClick(Sender: TObject);
var
name:String;
begin
name:=ExtractFilePath(Paramstr(0))+'english.ini';
Myini:=TiniFile.Create(name);
GroupBox1.Caption:=Myini.ReadString('language','GroupBox1','');
RBEnglish.Caption:=Myini.ReadString('language','RBEnglish','');
RBTw.Caption:=Myini.ReadString('language','RBTw','');
Button1.Caption:=Myini.ReadString('language','Button1','');
Label1.Caption:=Myini.ReadString('language','Label1','');
GroupBox1.Hint:=Myini.ReadString('language','GroupBox1','');
RBEnglish.Hint:=Myini.ReadString('language','RBEnglish','');
RBTw.Hint:=Myini.ReadString('language','RBTw','');
Button1.Hint:=Myini.ReadString('language','Button1','');
Label1.Hint:=Myini.ReadString('language','Label1','');
ComboBox1.Text:='English';
end;

procedure TForm1.RBTwClick(Sender: TObject);
var
name:String;
begin
name:=ExtractFilePath(Paramstr(0))+'TaiWan.ini';
Myini:=TiniFile.Create(name);
GroupBox1.Caption:=Myini.ReadString('language','GroupBox1','');
RBEnglish.Caption:=Myini.ReadString('language','RBEnglish','');
RBTw.Caption:=Myini.ReadString('language','RBTw','');
Button1.Caption:=Myini.ReadString('language','Button1','');
Label1.Caption:=Myini.ReadString('language','Label1','');
GroupBox1.Hint:=Myini.ReadString('language','GroupBox1','');
RBEnglish.Hint:=Myini.ReadString('language','RBEnglish','');
RBTw.Hint:=Myini.ReadString('language','RBTw','');
Button1.Hint:=Myini.ReadString('language','Button1','');
Label1.Hint:=Myini.ReadString('language','Label1','');
ComboBox1.Text:='TaiWan';
end;

procedure TForm1.ComboBox1Change(Sender: TObject);
var
name:String;
begin
if ComboBox1.Text='English' then
begin
name:=ExtractFilePath(Paramstr(0))+'english.ini';
Myini:=TiniFile.Create(name);
GroupBox1.Caption:=Myini.ReadString('language','GroupBox1','');
RBEnglish.Caption:=Myini.ReadString('language','RBEnglish','');
RBTw.Caption:=Myini.ReadString('language','RBTw','');
Button1.Caption:=Myini.ReadString('language','Button1','');
Label1.Caption:=Myini.ReadString('language','Label1','');
GroupBox1.Hint:=Myini.ReadString('language','GroupBox1','');
RBEnglish.Hint:=Myini.ReadString('language','RBEnglish','');
RBTw.Hint:=Myini.ReadString('language','RBTw','');
Button1.Hint:=Myini.ReadString('language','Button1','');
Label1.Hint:=Myini.ReadString('language','Label1','');
end
else
begin
name:=ExtractFilePath(Paramstr(0))+'TaiWan.ini';
Myini:=TiniFile.Create(name);
GroupBox1.Caption:=Myini.ReadString('language','GroupBox1','');
RBEnglish.Caption:=Myini.ReadString('language','RBEnglish','');
RBTw.Caption:=Myini.ReadString('language','RBTw','');
Button1.Caption:=Myini.ReadString('language','Button1','');
Label1.Caption:=Myini.ReadString('language','Label1','');
GroupBox1.Hint:=Myini.ReadString('language','GroupBox1','');
RBEnglish.Hint:=Myini.ReadString('language','RBEnglish','');
RBTw.Hint:=Myini.ReadString('language','RBTw','');
Button1.Hint:=Myini.ReadString('language','Button1','');
Label1.Hint:=Myini.ReadString('language','Label1','');
end;
end;

end.
 
后退
顶部