产品需要支持中文、英文,以前在python+Django的一个项目中使用过GNU开发的xgettext这个开源的工具,感觉还是很好用的,灵活也很好控制。所以打算在Delphi里也使用它来支持多语言。上网找了一下找到一个dxgettext。
下载dxgettext
上网下载一个dxgettext,下载后只要引用其中的gnugettext.pas 文件即可.
我下载的gnugettext.pas 版本是Revision: 1.176.2.10. http://dybdahl.dk/dxgettext/ 是作者的主页.
Delphi工程中使用dxgettext
引用gnugettext.pas这个文件后,要使用dxgettext,开始有一些初始的设置,在工程dpr文件中设置,类似下面的.
begin
Application.Initialize;
TP_GlobalIgnoreClass(TFont);
Application.CreateForm(TForm1, Form1);
Application.Run;
End.
TP_GlobalIgnoreClass 指定那些类不会被翻译.我们也可以指定具体的类的属性不被翻译:如:TP_Ignore (self, 'Listbox1.Items')
其它的可以看一下作者网页上的手册,有详尽的说明.
在一个窗口中,如果有一些内容要翻译,那么在这个窗体创建时我们需要加入TranslateComponent 这个过程,不然这个窗体的翻译不会生效.
像以下这样的:
procedure TfMain.FormCreate(Sender: TObject);
begin
TranslateComponent(self);
End;
TranslateComponent会把指定的组件及其子组件都加到翻译的对像列表中.
也还有一些其它的方法可以加到翻译中去.
基本就是这些工作,现在我们要窗口的按钮能支持多语言.可以这样定义tbutton的caption:
Button1.Caption := _('按钮测试');
就这样就OK了.
po文件和mo
做po文件和mo文件就和xgettext是一样的了.
在运行目录下 locale\en\LC_MESSAGES 我创建了这样的目录,来保存英文mo文件
如po 文件内容
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2012-04-12 12:58\n"
"PO-Revision-Date: 2012-04-16 09:41+0800\n"
"Last-Translator: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: dxgettext 1.2.2\n"
"Language-Team: \n"
#. Programmer's name for it: dtlServerPage
#. Programmer's name for it: dtlOcxPage
#: PEAQENVRWebocx_TLB.pas:365
#: PEAQENVRWebocx_TLB.pas:367
msgid "按钮测试"
msgstr "Button test"
这样我的窗口中的Button就有文件和中文的支持了.把po转成 mo文件.就完成了.
在编程PO文件时要注意字符类型。
Delphi中多语言切换
要切换语言使用 UseLanguage过程即可,如我要切换到英文
UseLanguage('en'); 这样一句就行了
如果要切换回默认的
UseLanguage('default'); 即可.
如果实时多语言切换,问题来了,当我们这样切换时,窗口中的按钮呀什么的都没有刷新,需要把窗口关闭\打开,才把语言更改过来.什么窗口.控件repain都不行.
我现在使用的方法是:
self.Hide;
self.Show;
把窗体隐藏,再显示,这样才能把语言刷新过来,不过这样用户也感觉不到有什么问题,我的窗体hide,show里并不存在处理大的计算.
不知有没有更好的办法呢?
语言自定义的扩展
像我们使用的很多软件,有的用户都可以扩展其对语言的支持.
我需要做成这样的需求,如果新加一语言的支持,不用改程序,只要把语言文件mo放在安装的相应目录下即可.
我们在程序加载时读多语言文件的目录locale,遍历这个目录下的所有文件,在程序中动态创建一个子菜单,这样用户可以选择一个语言,就切换到那种语言.
而新加一种语言的支持,我们只要在咯locale目录下创建一个对应的目录即可.