程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 如何在程序中利用C++支持多國語言

如何在程序中利用C++支持多國語言

編輯:關於C++

本文以emule為例,探討一下多國語言支持的實現。選擇emule,因為它的多國語言支持實現的相當好,可以支持動態切換。而且最關鍵,它是開源的,可以直接通過源碼來研究它的實現技術。

emule是利用動態加載資源DLL來實現多語言切換的,每一個資源DLL中包含了一份對應某一語言的字符串表。在源碼的srchybridlang 路徑上可以發現一個lang解決方案,其中包含了差不多40個項目,每個項目編譯出來都是一個單獨的DLL。這些DLL在程序安裝時拷貝到指定的目錄中。每個DLL裡面都是一個大的string table。emule為每一個用到的字符串(大約為1400多個)都指定了一個固定ID,在不同的DLL中這個ID對應了這個字符串的不同語言的翻譯版本。這樣每當需要這個字串時就通過ID去獲取,在當時程序加載的某一特定語言的DLL,就可以取到相應語言的字串。

英文版本的string table編譯在主EXE文件中,這樣當某一語言不支持,或DLL文件加載失敗時還可以使用英語版本。

下面我們就看看具體的實現。

主要實現代碼在I18n.cpp文件中。入口函數是 void CPreferences::SetLanguage() ,這個函數在在 void CPreferences::LoadPreferences() 函數中被調用,即載入了程序的各種選項後。當程序第一次運行時,在選項文件(即 preferences.ini)中沒有內容,SetLanguage函數會根據系統的本地語言設置來加載對應的語言DLL資源,所以我們第一次安裝後就是中文,無需設置。這一點我們後面會說到。

另外在 BOOL CPPgGeneral::OnApply() 中也調用了該函數,即用戶在“選項”窗口中改變了語言選擇後。

在 void CPreferences::SetLanguage() 函數中,首先調用了 static void InitLanguages(const CString& rstrLangDir, bool bReInit = false) 函數。這個函數主要是通過遍歷“語言”目錄(即我們前面說地的,專門用於存放各種語言版本DLL的目錄),來初始化靜態“語言表” (_aLanguages),這是個靜態數組,其中的每一項對應一種支持的語言。凡能找到相應DLL文件的,就在表中標記該語言為支持。

然後調用 static bool LoadLangLib(const CString& rstrLangDir, LANGID lid) 來載入相應的語言DLL。這個函數比較簡單,通過查“語言表”(_aLanguages),如果要載入的語言是支持的,就加載相應的DLL文件,並將DLL模塊句柄存到_hLangDLL中,這也是一個靜態變量。我們可以看到如果是英語,是不需要加載的,直接用EXE模塊中的資源字符串表。

如果調用LoadLangLib文件加載指定的語言失敗,程序會嘗試判斷本地系統的語言集,並加載對應的語言,如果加載也失敗就使用英語。

語言文件加載成功後,程序會嘗試從中加載一個字串,如果失敗,說明可能DLL文件損壞,則再重設語言為英語。英語字串是內置在EXE文件中的,所以是最可靠的。

至此,加載成功,句柄保存在_hLangDLL靜態變量中。

最後在需要字符串的地方程序通過 CString GetResString(UINT uStringID, WORD wLanguageID) 或 CString GetResString(UINT uStringID) 函數加載相應的字符串。這個函數的功能很簡單,就是從_hLangDLL指定的模塊中加載字符串資源。如果_hLangDLL為 NULL就是從當前模塊加載,我們前面已經看到了,如果使用英語這個變量的值就是NULL。

在emule的源碼中,幾乎每個對話框都實現了一個Localize(void)函數,這個函數就是通過調用GetResString來設置對話框上所有控件的文字。在  BOOL CPPgGeneral::OnApply() 函數中我們可以看到,在調用CPreferences::SetLanguage函數切換了語言後,會依次調用對話框和窗口的Localize(void)函數,重新設置UI的文字內容。

最後注意一點,如果你想讓應用支持多語言,在設計對話框時要把對話框的Language屬性設為“非特定語言”。在“資源”視圖中選中相應的對話框節點,再切換到“屬性”視圖就可以看到這個選項了。如果不設置會出現亂碼。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved