• VC2008以资源形式实现多语言版本[转]


    转自:http://blog.csdn.net/akof1314/article/details/6321628

    越来越多的程序支持多语言切换,或者能自动适应当前系统语言,让自己开发的程序支持多语言不仅可以让自己的程序被国人使用,也能让外国程序爱好者使用。VC开发多语言程序有多种方法,或读取配置文件,或使用不同资源DLL等等。这里介绍以资源形式实现多语言版本。

    1.打开Visual Studio 2008,新建一个基于对话框工程,名称为LanguageTest,不使用Unicode库 ,资源语言一共有十种(当前操作系统为Windows 7简体中文版),如下图所示:
     
    在此选择“中文(简体,中国)”,单击“完成”按钮。
    2.在对话框设计界面上,放置一个按钮(ID号IDC_SHOW_BUTTON)、一个静态文本(ID号IDC_TEXT_STATIC,必须改其默认ID号)和一个编辑框(ID号IDC_TEXT_EDIT),资源视图如下所示:
     
    可以看到资源视图里面都是简体中文的资源文件,现在在“String Table”字符串表类型下,双击打开其子项“String Table”,默认只有一条字符串,是窗口菜单里的“关于 LanguageTest(&A)...”,如图所示:
     
    现在点一下第二行(以黑色外框标志),新建一条字符串(值会默认增长,注意不要与已有的冲突),“标题”是“ID”号所代表的字符串内容,我们增加字符串如下图所示:
     
    3.在“解决方案管理器”下双击打开“LanguageTestDlg.cpp”文件,在其初始化函数OnInitDialog()增加如下红色代码:

    BOOL CLanguageTestDlg::OnInitDialog() 

        CDialog::OnInitDialog(); 
     
        // 将“关于...”菜单项添加到系统菜单中。 
     
        // IDM_ABOUTBOX 必须在系统命令范围内。 
        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); 
        ASSERT(IDM_ABOUTBOX < 0xF000); 
     
        CMenu* pSysMenu = GetSystemMenu(FALSE); 
        if (pSysMenu != NULL) 
        { 
            BOOL bNameValid; 
            CString strAboutMenu; 
            bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX ); 
            ASSERT(bNameValid); 
            if (!strAboutMenu.IsEmpty()) 
            { 
                pSysMenu->AppendMenu(MF_SEPARATOR); 
                pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); 
            } 
        } 
     
        // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动 
        //  执行此操作 
        SetIcon(m_hIcon, TRUE);            // 设置大图标 
        SetIcon(m_hIcon, FALSE);        // 设置小图标 
     
        // TODO: 在此添加额外的初始化代码 
        CString strTemp; 
        strTemp.LoadString(IDS_SHOWBUTTON);    //LoadString读取一个ID号定义的字符串资源 
        SetDlgItemText(IDC_SHOW_BUTTON,strTemp); 
     
        strTemp.LoadString(IDS_TEXTSTATIC); 
        SetDlgItemText(IDC_TEXT_STATIC,strTemp); 
     
        strTemp.LoadString(IDS_TEXTEDIT); 
        SetDlgItemText(IDC_TEXT_EDIT,strTemp); 
        return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE 

     

    编译运行,结果如下图所示:
     
    4.制作英文版的“String Table”。右击“资源视图”下的“String Table”子项,选择“插入副本”,在弹出的对话框选择“英语(美国)”,如下图所示:
     
    “确定”按下之后,就会多出一个字符串资源来,并且在后面名称多了标记“[英语(美国)]”,双击打开其内容与简体中文字符串资源一样,如下图所示:
     
    将所有字符串修改“标题”内容为英文,如下图所示:
     
    再编译生成,此时应用程序就能适应简体中文操作系统和英文美国操作系统了,会自动显示为默认操作系统语言。可是由于此时没有英文版系统可以验证,无法确定是否完全正确,待以后验证。
    5.接下去,欲使用SetThreadLocale自由切换程序界面语言,在应用程序类初始化函数InitInstance()添加如下代码:

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

    运行程序,出现问号乱码情况,当前Windows 7系统的显示语言只有“中文(简体)”,而“当前系统区域设置”为“中文(简体,中国)”,如下图所示:

    自由切换语言失败,参考MSDN帮助文档,对的介绍说明:http://msdn.microsoft.com/en-us/library/dd374051%28VS.85%29.aspx

    Windows Vista and later: Do not use SetThreadLocale to select a user interface language. The resource loader selects the resource that is defined in the .rc file with a LANGUAGE statement, or the application can use FindResourceEx. Additionally, the application can use SetThreadUILanguage. 
     
    Windows 2000, Windows XP: Do not use SetThreadLocale to select a user interface language. To select the resource that is defined in the .rc file with a LANGUAGE statement, the application must use the FindResourceEx function.

    另有一篇文章讨论SetThreadLocale no longer changes GUI language in Vistahttp://social.msdn.microsoft.com/Forums/en/windowscompatibility/thread/d3a44b1c-900c-4c64-bdf8-fe94e46722e2

    替换成如下代码:

    SetThreadUILanguage(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US)); 

    运行发现可以显示“英文”资源字符串,如下图所示:
     
    可以使用GetUserDefaultUILanguage()判断当前用户界面语言,如下当用户界面语言为“简体中文”时,设置为“英文(美国)”:

    if  (GetUserDefaultUILanguage() == MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED)) 

        SetThreadUILanguage(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US)); 

     

    在Windows XP简体中文版下,非Unicode程序的语言为“中文(中国)”,代码页转换表有包含“US-ASCII”,在Windows 7下未找到“代码页转换表”,使用SetThreadLocale和SetThreadUILanguage(注:静态链接然后到XP下测试的 )都能将用户界面语言设置成“英文(美国)”,如下图所示:

    改变“控制面板”里面的“区域选项”语言为“英语(美国)”,则显示成问号,原因在于SetThreadLocale设置的语言与“区域选项”里面的语言一样,若是一样,则不操作,如下图所示:

     

    在此中英文版本资源下,在中英文系统语言环境下,就会自动切换不同语言资源,然后在另外系统语言环境下(如:日语),就设定程序语言为英文(英文在大多数系统下都支持),代码如下:(未能完全测试)

    [cpp] view plaincopy
     
    1. if ((GetSystemDefaultLangID() != MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)) &&  
    2.         (GetSystemDefaultLangID() != MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)))  
    3. {  
    4.     OSVERSIONINFO ovs;  
    5.     ovs.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);  
    6.     if (::GetVersionEx(&ovs))  
    7.     {  
    8.         if (ovs.dwPlatformId == VER_PLATFORM_WIN32_NT && ovs.dwMajorVersion >= 6 &&  
    9.                 ovs.dwMinorVersion >= 0)  
    10.         {  
    11.             SetThreadUILanguage(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));  
    12.         }  
    13.         else  
    14.             SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT));  
    15.     }  
    16. }  

    参考资料:

    1.编写 Win32 多语言用户界面应用程序 http://msdn.microsoft.com/zh-cn/goglobal/bb688160 
    2.SetThreadUILanguage http://msdn.microsoft.com/en-us/library/dd374053%28VS.85%29.aspx
    3.SetThreadLocale http://msdn.microsoft.com/en-us/library/dd374051%28VS.85%29.aspx 
    4.语言标识符常量和字符串 http://msdn.microsoft.com/en-us/library/dd318693%28VS.85%29.aspx 
    5.LoadString的如何确定load哪个语言的资源?http://topic.csdn.net/u/20080504/15/fb71cf4e-8420-4c1d-b89e-2784ba3dfca9.html

  • 相关阅读:
    将博客搬至CSDN
    NOIP2018酱油记
    CF 1039D You Are Given a Tree && CF1059E Split the Tree 的贪心解法
    最大异或子序列问题
    UVa 10615
    UVa 1057
    用树状数组代替平衡树
    [CTSC2008]图腾totem
    POI2008 题解
    简便思路的题目别人的做法
  • 原文地址:https://www.cnblogs.com/vranger/p/3938355.html
Copyright © 2020-2023  润新知