zoukankan      html  css  js  c++  java
  • 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();
    }

  • 相关阅读:
    Redis分布式锁服务(转)
    redis分布式锁(转)
    MySQL+InnoDB semi-consitent read原理及实现分析(转)
    MySQL加锁处理分析(转)
    实战经验丨PHP反序列化漏洞总结
    脚本语言丨Batch入门教程第四章:调用与传参
    福利狂欢已开启,请做好准备!
    脚本语言丨Batch入门教程第三章:逻辑判断
    WinRAR存在严重的安全漏洞影响5亿用户
    Batch入门教程丨第二章:认识变量相关概念
  • 原文地址:https://www.cnblogs.com/lishennan/p/4362107.html
Copyright © 2011-2022 走看看