MFC开发软件支持多语言且同时支持xp和win7操作系统

参考资料:

http://www.cnblogs.com/xiaoyusmile/p/3924931.html

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

通过以上两种方案总结实现动态软件支持多语言,不需要重新启动程序:

1:在应用程序.APP中添加两个函数:

//打开窗口

INT_PTR CMuliteLanguageApp::OpenWindow(void)
{
CMuliteLanguageDlg dlg;
m_pMainWnd = &dlg; 
INT_PTR nResponse=dlg.DoModal();
return nResponse;
}

//获取配置文件中的语言,并加载在线程中,该函数必须在窗口创建前调用
void CMuliteLanguageApp::LoadLanguage(void)
{

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();
if (operatingSystem==win_win7)
{
SetThreadUILanguage(lcidThread);//是由于win7和xp系统调用的函数不一样,所以首先得到操作系统
}
else
{
SetThreadLocale(lcidThread);
}
m_curThreadID=lcidThread;
}
else
{
m_curThreadID=GetSystemDefaultLangID();//获取默认用户设置语言
}

}

//获取操作系统

//win_win7是自己定义的一个宏
INT_PTR CMuliteLanguageApp::GetOperatingSystem()
{
OSVERSIONINFO osvi;
BOOL bIsWindowsXPorLater;

ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

GetVersionEx(&osvi);
if (osvi.dwMajorVersion>=6&&osvi.dwMinorVersion>=0)
{
return win_win7;
}
else
{
return win_xp;
}
}

2.InitInstance()函数更改:

BOOL CMuliteLanguageApp::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;

// 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
//CMuliteLanguageDlg dlg;
//m_pMainWnd = &dlg;
//INT_PTR nResponse = dlg.DoModal();

operatingSystem=GetOperatingSystem();
LoadLanguage();
INT_PTR nResponse = OpenWindow();
if (nResponse == IDOK)
{
// TODO: 在此放置处理何时用
// “确定”来关闭对话框的代码
}
else if (nResponse == IDCANCEL)
{
// TODO: 在此放置处理何时用
// “取消”来关闭对话框的代码
}

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

// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。
return FALSE;
}

3.在对话框类中添加菜单响应函数:

void CMuliteLanguageDlg::OnLanguageSwitch()
{
// TODO: 在此添加命令处理程序代码
CMuliteLanguageApp*pApp = (CMuliteLanguageApp*)AfxGetApp();

//LCID lcidNew = GetThreadLocale();//win7时用GetThreadUILanguage();

lcidNew=pApp->m_curThreadID;
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();

//销毁当前窗口 
pApp->m_pMainWnd = NULL;
this->DestroyWindow();

//创建新的窗口
pApp->LoadLanguage();
pApp->OpenWindow();
}

方法二:加载动态库的方法

在.cpp应用文件

BOOL CTestMulitLanguageApp::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;

// 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
LoadLanguage();
OpenWindow();

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

// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。
return FALSE;
}

int CTestMulitLanguageApp::GetLang(void)
{
return m_Lang;
}
void CTestMulitLanguageApp::LoadLanguage(void)
{
CString strDLL;
HINSTANCE hLanguageDll, hLanguageNow;

//保存本身的资源句柄
static HINSTANCE hOriginalHandle = ::AfxGetResourceHandle();

//读取ini配置文件
CString strFileName = _T("Language.ini");
if (PathFileExists(strFileName))

int lang = 0;
CFile file;
file.Open(strFileName, CFile::modeRead | CFile::typeBinary);
file.Read(&lang, sizeof(lang));
file.Close();
m_Lang = lang;
}

//根据用户喜好来设置
if (m_Lang == ENGLISH)//英文
hLanguageDll = ::AfxLoadLibrary(_T("English"));
else if (m_Lang == CHINESE)//中文
hLanguageDll = hOriginalHandle;
else
{
//用户未指定,则根据系统选择合适语言,默认为英文
WORD wLangPID = PRIMARYLANGID(GetSystemDefaultLangID()); 
if (wLangPID == LANG_CHINESE)
hLanguageDll = hOriginalHandle;
else if (wLangPID == LANG_ENGLISH)
hLanguageDll = ::AfxLoadLibrary(_T("English"));
else
hLanguageDll = ::AfxLoadLibrary(_T("English"));

//保存已加载的资源DLL句柄
hLanguageNow = ::AfxGetResourceHandle(); 
//加载新的资源DLL
if(hLanguageDll)
::AfxSetResourceHandle(hLanguageDll); 
//释放之前加载的资源DLL
if (hLanguageNow != hOriginalHandle)
FreeLibrary(hLanguageNow);
}
void CTestMulitLanguageApp::OpenWindow(void)
{
CTestMulitLanguageDlg dlg;
m_pMainWnd = &dlg; 
dlg.DoModal();
}

在dlg文件

void CTestMulitLanguageDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
CTestMulitLanguageApp*pApp = (CTestMulitLanguageApp*)AfxGetApp();

int old_Lang = pApp->GetLang();
int new_Lang = 0;
if(old_Lang == ENGLISH)
new_Lang = CHINESE;
else
new_Lang = ENGLISH;

CFile file;
file.Open(_T("Language.ini"), CFile::modeWrite | CFile::modeCreate | CFile::typeBinary);
file.Write(&new_Lang, sizeof(new_Lang));
file.Close();

//销毁当前窗口 
pApp->m_pMainWnd = NULL;
this->DestroyWindow();

//创建新的窗口
pApp->LoadLanguage();
pApp->OpenWindow();
}

猜你喜欢

转载自blog.csdn.net/zb774095236/article/details/86063608
今日推荐