實現MFC多語言版本

    百度了一番,MFC實現多國語言有很多方法:
html

  • VS提供對話框的「插入副本」方法;
    shell

  • 將要顯示的界面文字作一個相似ini文件,加載界面的時候各控件用SetWindowText來顯示不一樣的語言內容;
    框架

  • 製做Dll資源文件,不一樣語言調用不一樣的Dll;
    ide

    等等不一樣招數,網上各路神仙各有方法來實現之。
函數


    綜合下來本人以爲Dll資源文件比較喜歡,嘗試寫了一個例程。
工具

    開發環境:Win7 64位 專業版、Visual Studio 2012 專業版。
ui

    OK,開工。
.net


    VS中新建一個MFC項目:
翻譯

    【文件】——【新建】——【項目】,選擇「MFC 應用程序」,項目名稱:MFCApp,位置:MultiLanguage。
3d

    選擇「基於對話框」,取消「使用 Unicode 庫」。

    wKiom1S2JdXymxMJAAJa7Yikw2g828.jpg

    【完成】,結束應用程序嚮導的配置。


    自由發揮一下,作一個程序界面:

    wKiom1S2KZLBLwgGAABFlFzsiB0932.jpg

    控件編輯:

ID
控件類型 Caption
IDC_EDIT_SHOW Edit Control
IDC_BUTTON_SPEAK Button 快說!


     再弄一個菜單:

    wKiom1S2K4bisMk1AABwJeqv9jg797.jpg

    菜單ID:

ID Caption
ID_CN 中文
ID_EN 英文
ID_JP 日語
ID_GM 德文


    Dll資源製做的準備工做:

    將MFCApp中的「資源文件」下的文件「移除」(「移除」後文件還在,並無被「刪除」);

    將「頭文件」下的「Resource.h」移除。

    wKioL1S2MP_xEBwCAAC7IUBhQ0k175.jpg


    建立英文版的Dll。

    VS中,【文件】——【添加】——【新建項目】

    選擇「MFC DLL」,新項目名稱「English」,放在「MultiLanguage」文件夾下。

    wKiom1S2MtLAS_q9AADwS2ccodk417.jpg

    MFC DLL嚮導不作修改,採用默認的共享MFC DLL規則設置,【完成】。

    wKioL1S2NNmDTNnRAADHTuJc3Lc445.jpg


    刪除DLL中不須要的文件:

    「資源文件」下的文件,「頭文件」下的Resource.h。

    wKioL1S2NZmRDLbNAADbgLdvbwc145.jpg


    導入相關文件:

    將\MultiLanguage\MFCApp\MFCApp下的「MFCApp.rc」、「resource.h」複製到英文DLL項目的文件夾\MultiLanguage\English下。

    而後將MFCApp的\MultiLanguage\MFCApp\MFCApp\res文件夾中的文件所有複製到英文DLL項目對應的文件夾下。

    再將上述文件添加到 English 項目中。

    右擊English項目,【添加】——【現有項】

    wKiom1S2OAug6NL7AAIsO59Q7vE418.jpg

    完成後以下圖所示:

    wKiom1S2OKSD4l06AADDQMNZuOc804.jpg


    修改 English 項目中相關資源的語言屬性。

    wKiom1S2ObSRXl7YAAGNgT8x6C0197.jpg


    把English項目中的相關界面翻譯爲英文版,也包括菜單哦。

    wKioL1S2PBzgO6oPAABBy10atTo937.jpg


    修改English項目屬性。【配置屬性】——【連接器】——【高級】,「無入口點」改成「是(/NOENTRY)」。

    wKiom1S2PLqhA0QgAAMXnCNRAKc785.jpg


    而後就能夠按下 F7 生成 DLL 文件了。

    生成成功,不過有一堆warning,本人水平有限,索性無視了,能幹活就行。\(≧▽≦)/~

    wKiom1S2PkXCsV5DAAILCtmZ1Dg049.jpg


    按English項目的方法可建立中文、日語、德語版本。


    再回到久違的MFCApp上。

    MFCApp.h頭文件中:

// 添加宏定義
#define LANG_CHINESE	0
#define LANG_ENGLISH	1
#define LANG_JAPNESE	2
#define LANG_GERMAN	3

    類中添加成員變量:

class CMFCAppApp : public CWinApp
{
public:
	CMFCAppApp();

// 重寫
public:
	virtual BOOL InitInstance();

// 新添加代碼
private:
	int m_nLanguage;
	HINSTANCE m_hLangDLL;

// 實現

	DECLARE_MESSAGE_MAP()
};


    MFCApp.cpp文件中:

    構造函數初始化

// CMFCAppApp 構造

CMFCAppApp::CMFCAppApp()
{
	// 支持從新啓動管理器
	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;

	// TODO: 在此處添加構造代碼,
	// 將全部重要的初始化放置在 InitInstance 中

	// 新增代碼
	// 初始化變量
	m_nLanguage=0;
	m_hLangDLL=NULL;
}

    在InitInstance()函數中增長導入語言DLL的代碼

// CMFCAppApp 初始化

BOOL CMFCAppApp::InitInstance()
{
	// 若是一個運行在 Windows XP 上的應用程序清單指定要
	// 使用 ComCtl32.dll 版本 6 或更高版原本啓用可視化方式,
	//則須要 InitCommonControlsEx()。不然,將沒法建立窗口。
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	// 將它設置爲包括全部要在應用程序中使用的
	// 公共控件類。
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);

	CWinApp::InitInstance();


	AfxEnableControlContainer();

	// 建立 shell 管理器,以防對話框包含
	// 任何 shell 樹視圖控件或 shell 列表視圖控件。
	CShellManager *pShellManager = new CShellManager;

	// 激活「Windows Native」視覺管理器,以便在 MFC 控件中啓用主題
	CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));

	// 標準初始化
	// 若是未使用這些功能並但願減少
	// 最終可執行文件的大小,則應移除下列
	// 不須要的特定初始化例程
	// 更改用於存儲設置的註冊表項
	// TODO: 應適當修改該字符串,
	// 例如修改成公司或組織名
	SetRegistryKey(_T("應用程序嚮導生成的本地應用程序"));


// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
	// 新增代碼。語言選擇

	// 讀取 INI 文件中的設置
	CString strIniFile="Config.ini";
	m_nLanguage=::GetPrivateProfileInt("Language","Current",0,strIniFile);

	// 加載對應的 DLL 文件
	switch (m_nLanguage)
	{
	case LANG_CHINESE:
		m_hLangDLL=::LoadLibrary("Chinese.dll");
		break;
	case LANG_ENGLISH:
		m_hLangDLL=::LoadLibrary("English.dll");
		break;
	case LANG_JAPANESE:
		m_hLangDLL=::LoadLibrary("Japanese.dll");
		break;
	case LANG_GERMAN:
		m_hLangDLL=::LoadLibrary("German.dll");
		break;
	default:
		m_hLangDLL=::LoadLibrary("Chinese.dll");
		break;
	}

	if (m_hLangDLL!=NULL)
	{
		AfxSetResourceHandle(m_hLangDLL);
	}
	else
	{
		AfxMessageBox("語言DLL文件加載失敗!");
		exit(1);		// 非正常終止程序
	}

// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

	CMFCAppDlg dlg;
	m_pMainWnd = &dlg;
	INT_PTR nResponse = dlg.DoModal();
	if (nResponse == IDOK)
	{
		// TODO: 在此放置處理什麼時候用
		//  「肯定」來關閉對話框的代碼
	}
	else if (nResponse == IDCANCEL)
	{
		// TODO: 在此放置處理什麼時候用
		//  「取消」來關閉對話框的代碼
	}
	else if (nResponse == -1)
	{
		TRACE(traceAppMsg, 0, "警告: 對話框建立失敗,應用程序將意外終止。\n");
		TRACE(traceAppMsg, 0, "警告: 若是您在對話框上使用 MFC 控件,則沒法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
	}

	// 刪除上面建立的 shell 管理器。
	if (pShellManager != NULL)
	{
		delete pShellManager;
	}

	// 因爲對話框已關閉,因此將返回 FALSE 以便退出應用程序,
	//  而不是啓動應用程序的消息泵。
	return FALSE;
}

    在類的最後,加入收尾工做:

// CMFCAppApp 收尾

int CMFCAppApp::ExitInstance()
{
	// TODO: 在此添加專用代碼和/或調用基類

	// 新增代碼。釋放所加載的 DLL 資源
	if(m_hLangDLL)
	{
		AfxFreeLibrary(m_hLangDLL);
	}
	
	return CWinApp::ExitInstance();
}


    至此,大致框架已經搭建完成j_0051.gif,其他部分可查看源代碼。走起,看看效果吧!

    wKioL1S3gB2TRnndAACenIFxao8275.jpg        wKiom1S3f1HTXxtkAACC_5IWPFo187.jpg


    另外,文本框中的顯示內容採用了從配置文件讀取的方式。若是哪位以爲須要將程序打造得能適應更多的語言,能夠嘗試根據配置文件動態生成程序界面和菜單。

    本例中本人作了一個配置文件:Config.ini,內容以下:

[Language]
Current=2

[Text]
Chinese=你好,這是中文版
English=Hello World
Japanese=私は言うのは日本語です。(我說的是日語哦)
German=Ich sagte, IST Deutsch.(我說的是德語哦)


    其實本例的語言Dll文件本人只作了中文和英文的,至於日文和德文的就偷懶了一下,複製了中文的Dll文件,再用eXeScope工具進行了修改:

    wKioL1S3gUvAS8QyAAJrySgtNUY108.jpg


本文參考了網上很多前輩的大做,再次一併感謝!

http://blog.csdn.net/bdc995/article/details/2139125

http://blog.csdn.net/xiliang_pan/article/details/7822230

http://blog.csdn.net/huihui0121/article/details/7654116

http://www.360doc.com/content/12/0922/17/29694_237587201.shtml

相關文章
相關標籤/搜索