首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 程式實作多國語言動態切換:以 eMule 為例

     編輯:關於C++

前言

多國語言支援是國際化軟體的基本需求。本文以開源專案 eMule 為例,深入剖析其採用動態載入資源 DLL實現多語言無縫切換的完整架構與關鍵程式碼。

核心架構:資源 DLL + 字串表 ID 映射

  • 每種語言編譯成獨立 DLL(約 40 個專案,輸出 lang 目錄下)
  • 每個 DLL 內含一張完整的 String Table
  • 程式中每個顯示字串分配固定 Resource ID(約 1400+ 個)
  • 不同語言 DLL 中相同 ID 對應該語言的翻譯字串
  • 英文字串表內建於主 EXE,作為預設回退

關鍵程式碼流程解析

1. 語言初始化入口:CPreferences::SetLanguage()

於 LoadPreferences()(啟動載入設定時)與 CPPgGeneral::OnApply()(使用者變更語言設定時)被呼叫。

2. 掃描語言目錄建立語言表 _aLanguages

static void InitLanguages(const CString& rstrLangDir, bool bReInit = false) {
    // 遍歷語言目錄尋找 *.dll
    // 找到對應 DLL 則在靜態陣列 _aLanguages 標記該語言為支援
}

3. 載入指定語言 DLL LoadLangLib()

static bool LoadLangLib(const CString& rstrLangDir, LANGID lid) {
    // 查 _aLanguages 確認支援
    // 若為英文:直接使用 EXE 模組資源,_hLangDLL = NULL
    // 其他語言:LoadLibrary 載入 DLL,句柄存入靜態 _hLangDLL
    // 載入失敗則嘗試系統預設語言,再失敗回退英文
}

4. 驗證 DLL 完整性

載入成功後嘗試讀取一個測試字串,失敗視為 DLL 損毀,強制回退英文(EXE 內建資源最可靠)。

5. 統一字串取得介面 GetResString()

CString GetResString(UINT uStringID, WORD wLanguageID = 0) {
    HINSTANCE hInst = _hLangDLL ? _hLangDLL : AfxGetInstanceHandle();
    CString str;
    str.LoadString(hInst, uStringID);
    return str;
}

6. UI 文字動態套用 Localize()

幾乎每個對話框類別皆實作 Localize(void),遍歷控制項呼叫 GetResString 更新文字。語言切換後,依序呼叫所有開啟視窗的 Localize() 即時刷新介面。

重要設計細節

對話框資源屬性必須設為「非特定語言 (Language: Neutral)」

在資源檢視中選取對話框 → 屬性視窗 → Language 選擇 Neutral。若未設定,切換語言時會出現亂碼,因為資源編譯器會依預設語言編碼字串。

優勢總結

  • 動態切換:無需重啟應用程式
  • 擴充性佳:新增語言只需新增 DLL,無須重新編譯主程式
  • 回退機制完善:英文內建 EXE,任意失敗皆有預設
  • 原始碼開放:可直接參考 I18n.cpp 完整實作

適用場景

此架構適用於所有基於 MFC 的專案,亦可移植至純 Win32 API 專案(改用 LoadLibrary/FindResource/LoadString)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved