MFC的多國語言界面的實現


轉載請註明原文網址:

http://www.cnblogs.com/xianyunhe/archive/2011/09/02/2163842.html

目前很多軟件都是要出口到多個國家,因此,爲軟件提供多國語言支持就成爲了一個基本條件。爲軟件提供多國語言的支持的具體實現方法有很多,但基本原理都差不多,就是實現代碼和語言包的獨立,代碼根據設定的語言選擇語言包。

其中,MFC的資源文件就提供了對多國不同語言的支持功能,如果使用MFC開發,直接用資源文件自帶的多國語言支持,可以省去不少的麻煩。

下面就介紹給MFC程序添加中英文的支持,開發環境爲VS2010

1.  新建工程

新建了一個對話框工程,工程名稱爲MultiLanguages,默認語言選擇是“中文”。

2.  添加多國語言的資源

在創建工程後,工程會添加默認的資源,如主對話框,都是“中文”資源。現在我們需要添加相應的英文的資源文件。

爲主窗口IDD_MULTILANGUAGES添加英文資源的方法爲:

(1)       打開Resource View窗口。

(2)       右鍵IDD_MULTILANGUAGES,點擊彈出菜單中的“Insert Copy”菜單,如下圖所示。

(3)       彈出窗口資源複製語言選擇窗口,選擇語言爲“英語(美國)”,如下圖所示。

(4)       點擊OK,即完成英文版對話框的添加。完成添加後,IDD_MULTILANGUAGES就對應於兩個不同語言版本的對話框了,如下圖所示。

使用同樣的方法,也可以爲其他資源添加多國語言版本的支持。主要需要多國版本需要支持的有對話框、菜單和字符串。

添加多國語言的資源後,要對這些資源進行不同語言的定製,根據資源對應的語言,設置對話框和控件的標題等。

3.  Locale

程序的語言選擇跟操作系統語言(System Locale)、用戶設置語言(User Locale)和線程語言(Thread Locale)有關。程序運行時,是根據線程語言來選擇資源的。如果程序中未對線程語言進行設置,線程語言默認採用用戶設置語言。設置線程語言的函數是SetThreadLocale

設置線程語言爲“中文”的代碼如下:

SetThreadLocale(MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT));

 

設置線程語言爲“英語(美國)”的代碼如下:

SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT));

 

設置線程語言要在對話框創建之前,否則無法更改對話框的資源。可以在CMultiLanguagesApp::InitInstance函數中的對話框初始化之前添加線程語言設置,分別設置爲中文和英文語言,就可以查看到對話框界面的不同。

4.  字符串處理

程序的多國語言的支持,不僅包括界面的多國語言支持,也要包括各類字符串的多國語言支持,如彈出的提示信息。因此,在彈出提示信息時,也要爲提示信息創建多個語言版本,並根據當前線程的語言來選擇不同的提示信息。

例子:實現不同語言版本中按鈕的點擊次數的統計。

(1)       String Table中分別添加中英文的IDS_STRING_SAMPLE資源,內容如下表所示。

中文

這個一箇中文提示信息。\n點擊次數:%d

英文

This is a prompt message in English.\nClick Times:%d.

 

(2)       在主窗口控件中添加一個控件Button1,控件的中文名爲“提示”,英文名稱爲“Prompt”。爲該控件添加一個左鍵單擊消息響應函數,該函數的內容如下:

void CMultiLanguagesDlg::OnBnClickedButton1()

{

         // TODO: Add your control notification handler code here

         static int s_iClickTime = 0;

         s_iClickTime++;

         CString strPrompt = _T("");

         CString strFormat = _T("");

         strFormat.LoadString(IDS_STRING_SAMPLE);

         strPrompt.Format(strFormat, s_iClickTime);

         AfxMessageBox(strPrompt);

}

 

(3)       分別在CMultiLanguagesApp::InitInstance添加設置線程語言爲中文和英文的代碼,然後多次點擊按鈕進行測試。

中文版本彈出的提示框如下圖所示:

英文版本彈出的提示框如下圖所示:

5.  語言切換

窗口在初始化時候就導入了資源文件,在通過SetThreadLocale更換了線程語言後,窗口的資源並不會更改,必須要通過代碼來重新裝載資源。因爲窗口中存在多種與線程語言相關的資源,重新啓動軟件一種叫快捷的更新語言環境的方法。

例:通過菜單來進行語言切換,切換語言後重啓軟件。

(1)    爲程序添加中英文菜單選項ID_LANGUAGE_SWITCH,併爲該菜單添加消息響應函數,其中,m_bRestartFlag使用判斷關閉窗口時是否需要重啓程序的標識。代碼如下。

void CMultiLanguagesDlg::OnLanguageSwitch()

{

         // TODO: Add your command handler code here

         // 讀取當前線程的語言,並根據當前線程語言進行語言切換

         LCID lcidNew = GetThreadLocale();

         if (LANG_ENGLISH == PRIMARYLANGID(LANGIDFROMLCID(lcidNew)))

         {

                   lcidNew = MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT);

         }

         else

         {

                   lcidNew = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);

         }

 

         // 把語言設置寫入配置文件

         CFile file;

         file.Open(_T("Language.ini"), CFile::modeWrite | CFile::modeCreate | CFile::typeBinary);

         file.Write(&lcidNew, sizeof(lcidNew));

         file.Close();

 

         // 關閉窗口

         m_bRestartFlag = TRUE;

         PostMessage(WM_CLOSE, 0, 0);

}

 

(2)    在關閉窗口時,重啓動該程序。即在窗口響應WM_CLOSE時,重啓程序。代碼如下:

void CMultiLanguagesDlg::OnClose()

{

         // TODO: Add your message handler code here and/or call default

         // 判斷是否需要重新啓動窗口

         if (m_bRestartFlag)

         {

                   CString strFileName = _T("");

                   GetModuleFileName(NULL, strFileName.GetBuffer(MAX_PATH), MAX_PATH);

                   ShellExecute(NULL, _T(""), strFileName, NULL, NULL, SW_SHOWNORMAL);

                   strFileName.ReleaseBuffer();

         }

 

         CDialogEx::OnClose();

}

 

(3)    在啓動軟件時,根據當前軟件的配置文件中語言來設置線程語言,即在CMultiLanguagesApp::InitInstance函數中創建對話框之前設置線程語言,代碼如下:

         // 判斷你是否存在配置文件,如果存在,從配置文件中讀取語言設置

         CString strFileName = _T("Language.ini");

         if (PathFileExists(strFileName))

         {

                   LCID lcidThread = 0;

                   CFile file;

                   file.Open(strFileName, CFile::modeRead | CFile::typeBinary);

                   file.Read(&lcidThread, sizeof(LCID));

                   file.Close();

                   SetThreadLocale(lcidThread);

         }

 

(4)       通過點擊菜單來測試軟件的語言切換。

6. MessageBox的問題

由於MessageBox中的按鈕的語言是跟操作系統相關的,要想實現MessageBox按鈕的多語言化是很有一定難度的。我現在還沒有查到好的解決方法,很多網友的建議是拋棄MessageBox,自己建立對話框。

  7. 源代碼

源代碼的下載鏈接如下:

http://files.cnblogs.com/xianyunhe/MultiLanguages.rar

 

8. 相關函數和類型

與本地化相關的函數和類型如下:

 GetSystemDefaultLCID

GetSystemDefaultLocaleName

GetUserDefaultLCID

GetUserDefaultLocaleName

SetThreadLocale

GetThreadLocale

 

MAKELCID

MAKELANGID

LCIDToLocalName

LocalNameToLCID

LANGIDFROMLCID

PRIMARYLANGID

 

LCID

LANGID

LANG_CHINESE 0x04

LANG_ENGLISH 0x09


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章