產品需要支援中文、英文,以前在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目錄下建立一個對應的目錄即可.