多國語言支援是國際化軟體的基本需求。本文以開源專案 eMule 為例,深入剖析其採用動態載入資源 DLL實現多語言無縫切換的完整架構與關鍵程式碼。
lang 目錄下)CPreferences::SetLanguage()於 LoadPreferences()(啟動載入設定時)與 CPPgGeneral::OnApply()(使用者變更語言設定時)被呼叫。
_aLanguagesstatic void InitLanguages(const CString& rstrLangDir, bool bReInit = false) {
// 遍歷語言目錄尋找 *.dll
// 找到對應 DLL 則在靜態陣列 _aLanguages 標記該語言為支援
}
LoadLangLib()static bool LoadLangLib(const CString& rstrLangDir, LANGID lid) {
// 查 _aLanguages 確認支援
// 若為英文:直接使用 EXE 模組資源,_hLangDLL = NULL
// 其他語言:LoadLibrary 載入 DLL,句柄存入靜態 _hLangDLL
// 載入失敗則嘗試系統預設語言,再失敗回退英文
}
載入成功後嘗試讀取一個測試字串,失敗視為 DLL 損毀,強制回退英文(EXE 內建資源最可靠)。
GetResString()CString GetResString(UINT uStringID, WORD wLanguageID = 0) {
HINSTANCE hInst = _hLangDLL ? _hLangDLL : AfxGetInstanceHandle();
CString str;
str.LoadString(hInst, uStringID);
return str;
}
Localize()幾乎每個對話框類別皆實作 Localize(void),遍歷控制項呼叫 GetResString 更新文字。語言切換後,依序呼叫所有開啟視窗的 Localize() 即時刷新介面。
對話框資源屬性必須設為「非特定語言 (Language: Neutral)」
在資源檢視中選取對話框 → 屬性視窗 → Language 選擇 Neutral。若未設定,切換語言時會出現亂碼,因為資源編譯器會依預設語言編碼字串。
I18n.cpp 完整實作此架構適用於所有基於 MFC 的專案,亦可移植至純 Win32 API 專案(改用 LoadLibrary/FindResource/LoadString)。