軟體國際化最直觀需求是選單文字動態切換。傳統作法是建立多個 DLL 資源檔,運行時 LoadLibrary 切換,但流程繁瑣、需處理資源重導向、對新手門檻高。本文介紹直接編輯 .rc 檔文字區段,在同一專案內維護多套選單資源,配合 CMenu::LoadMenu 動態載入,零 DLL 依賴、極簡易維護。
IDR_MAINFRAME MENU PRELOAD DISCARDABLE
BEGIN
POPUP "檔案(&F)"
BEGIN
MENUITEM "新建(&N)\tCtrl+N", ID_FILE_NEW
MENUITEM "開啟(&O)...\tCtrl+O", ID_FILE_OPEN
...
END
POPUP "編輯(&E)" ... END
POPUP "檢視(&V)" ... END
POPUP "說明(&H)" ... END
END
IDR_ENGLISH_MAINFRAME (或 IDR_MAINFRAME_ENGLISH)。"File(&F)", "New(&N)\tCtrl+N" 等。ID_FILE_NEW 等) 保持不變,確保訊息對應正確。IDR_ENGLISH_MAINFRAME MENU PRELOAD DISCARDABLE
BEGIN
POPUP "File(&F)"
BEGIN
MENUITEM "New(&N)\tCtrl+N", ID_FILE_NEW
MENUITEM "Open(&O)...\tCtrl+O", ID_FILE_OPEN
...
END
POPUP "Edit(&E)" ... END
POPUP "View(&V)" ... END
POPUP "Help(&H)" ... END
END
在 CMainFrame 增加成員 CMenu m_CurrentMenu,提供切換函式:
void CMainFrame::SwitchMenu(UINT nMenuID) {
if (m_CurrentMenu.m_hMenu) m_CurrentMenu.DestroyMenu();
m_CurrentMenu.LoadMenu(nMenuID); // 載入指定資源 ID
SetMenu(&m_CurrentMenu); // 套用至框架視窗
DrawMenuBar(); // 立即重繪
}
InitInstance() 中依登錄/設定檔決定 SwitchMenu(IDR_MAINFRAME) 或 SwitchMenu(IDR_ENGLISH_MAINFRAME)。OnLanguageChinese() / OnLanguageEnglish() 呼叫 SwitchMenu。| 優點 | 缺點/限制 |
|---|---|
| 無需額外 DLL,部署簡單 | 所有語言資源編譯進同一 EXE,體積隨語言數增大 |
| 資源編輯器可視化編輯雙語選單 | 僅解決選單,對話框、字串表等仍需其他機制 |
| 切換即時,無需重啟 | 大型專案建議改用 Satellite DLL 方案 |
SwitchMenu 封裝為 CLanguageManager 單例,統一管理選單、工具列提示、狀態列字串、對話框範本切換。CStringTable 多語言字串表 (ID 對應多語言),運行時 LoadString 取用。AfxSetResourceHandle 切換。