experiment: UI中的资源字符串国际化
发布日期:2021-06-30 22:19:34 浏览次数:2 分类:技术文章

本文共 6978 字,大约阅读时间需要 23 分钟。

使用<<>> http://blog.csdn.net/lostspeed/article/details/8520284, 在UI中使用多国语言

工程下载点:

效果图:

英国英语UI

简体中文UI

Demo中使用的多国语言集合 : 简体中文, 英国英语.

当扩展其他语言的支持, 增加对应语系的语言资源. 资源文件采用UnicodeIni文件存储.

默认的国际化语言是本地化语言, 可以指定UI要使用的语言.

/// @fn         UseLanguageId    /// @brief      指定使用的国际化语言    /// @param      bool bLocalLanguage, true = 语言ID是本地语言, false = 可以指定使用的语言    /// @param      由MAKELANGID宏指定的语言ID, 当(true != bLocalLanguage)时, 一定要指定语言ID    ///             e.g. 在中文下使用英文的UI    void UseLanguageId(bool bLocalLanguage = true, DWORD dwLangId = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
void CLanguageRes::UseLanguageId(bool bLocalLanguage, DWORD dwLangId){    m_dwLanguageId = bLocalLanguage ? GetUserDefaultUILanguage() : dwLangId;    m_bFindLocalLanguageRes = FindLanguageId(m_dwLanguageId);    m_strLocalLanguageSection = GetLanguageSectionById(m_dwLanguageId);}

定义了资源ID录入宏, 方便载入和使用资源ID

/// 转换窗体本身的国际化资源 e.g. 窗体标题#define CONVERT_LANG_RES_WND(pLanguageRes, hWnd, resId) \    if (NULL != (pLanguageRes)) \    ::SetWindowText((hWnd), (pLanguageRes)->LangResLoadString(L#resId).c_str());/// 转换给定窗体控件的国际化资源 e.g. 对话框的 IDOK 按钮#define CONVERT_LANG_RES_CTRL(pLanguageRes, hWnd, resId) \    if (NULL != (pLanguageRes)) \    ::SetDlgItemText((hWnd), (resId), (pLanguageRes)->LangResLoadString(L#resId).c_str());
载入资源字符串简洁.

void CAboutDlg::convertLangRes(){    CONVERT_LANG_RES_WND(LangResGet(), this->m_hWnd, IDD_SRCCIPHERUI_DIALOG);    CONVERT_LANG_RES_CTRL(LangResGet(), this->m_hWnd, IDC_STATIC_PROG_INFO);    CONVERT_LANG_RES_CTRL(LangResGet(), this->m_hWnd, IDC_STATIC_COPY_RIGHT);    CONVERT_LANG_RES_CTRL(LangResGet(), this->m_hWnd, IDOK);}
定义了程序中支持的国际化语言结构数组, 方便维护

#pragma pack(1)typedef struct _tag_LanguageId{    DWORD   wPrimLangId;    ///< Prim. lang. symbol    DWORD   wSubLangId;    ///< Sublang. symbol    _tag_LanguageId()    {        this->wPrimLangId = 0;        this->wSubLangId = 0;    }    _tag_LanguageId(WORD wPrimLangId, WORD wSubLangId)    {        this->wPrimLangId = wPrimLangId;        this->wSubLangId = wSubLangId;    }}TAG_LANGUAGE_ID;#pragma pack()const TAG_LANGUAGE_ID g_arrLanguageId[] = {    TAG_LANGUAGE_ID(LANG_CHINESE_SIMPLIFIED,SUBLANG_CHINESE_SIMPLIFIED),    ///< 简体中文    TAG_LANGUAGE_ID(LANG_ENGLISH, SUBLANG_ENGLISH_US),                      ///< 英文};

资源文件的录入, Demo中采用直接生成资源文件. 实际应用时, 应建立另外的资源录入程序.

CLanguageRes *  g_pLangRes  =   NULL;void CreateLangRes(){    std::wstring    strLangResPathName  =   L"";    strLangResPathName = GetTheModulePath();    strLangResPathName += L"LangRes.ini";    g_pLangRes = new CLanguageRes((wchar_t *)strLangResPathName.c_str());    _ASSERT(NULL != g_pLangRes);#ifdef ONLY_USE_ENGLISH    /// 如果不管操作系统代码页如何, 都要使用英文. 指定语言ID    /// 可以由用户在程序菜单上的语言ID列表选择后, 执行设置语言ID    g_pLangRes->UseLanguageId(false, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));#endif}void BuildLangRes(){      ///< 制作国际化资源, 只需一次, 有了国际化资源文件后, 注释掉 NEED_MAKE_LANGUAGE_RESOUCE#ifdef NEED_MAKE_LANGUAGE_RESOUCE    DWORD           dwLangIdCn          =   MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_CHINESE_SIMPLIFIED);    DWORD           dwLangIdEn          =   MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);    _ASSERT(NULL != g_pLangRes);    /// 建立多语言条目, 建立完成后,以后可以手工在语言文件中添加, 或做个语言文件录入程序    /// 制作中文资源, 英文资源, ...//     #define IDM_ABOUTBOX                    0x0010//     #define IDD_ABOUTBOX                    100//     #define IDS_ABOUTBOX                    101    g_pLangRes->LangResSaveString(L"IDS_ABOUTBOX", L"关于...", dwLangIdCn);    g_pLangRes->LangResSaveString(L"IDS_ABOUTBOX", L"about ...", dwLangIdEn);//     #define IDD_SRCCIPHERUI_DIALOG          102    g_pLangRes->LangResSaveString(L"IDD_SRCCIPHERUI_DIALOG", L"加解密算法UI", dwLangIdCn);    g_pLangRes->LangResSaveString(L"IDD_SRCCIPHERUI_DIALOG", L"CipherUI", dwLangIdEn);//     #define IDR_MAINFRAME                   128//     #define IDC_BTN_LOAD_PLAINTEXT          1000    g_pLangRes->LangResSaveString(L"IDC_BTN_LOAD_PLAINTEXT", L"载入明文", dwLangIdCn);    g_pLangRes->LangResSaveString(L"IDC_BTN_LOAD_PLAINTEXT", L"load plaintext", dwLangIdEn);//     #define IDC_BTN_CIPHER                  1001    g_pLangRes->LangResSaveString(L"IDC_BTN_CIPHER", L"加密", dwLangIdCn);    g_pLangRes->LangResSaveString(L"IDC_BTN_CIPHER", L"Encrypt", dwLangIdEn);//     #define IDC_BTN_LOAD_CIPHERTEXT         1002    g_pLangRes->LangResSaveString(L"IDC_BTN_LOAD_CIPHERTEXT", L"载入密文", dwLangIdCn);    g_pLangRes->LangResSaveString(L"IDC_BTN_LOAD_CIPHERTEXT", L"Load Cipher text", dwLangIdEn);//     #define IDC_BTN_LOAD_KEY                1003    g_pLangRes->LangResSaveString(L"IDC_BTN_LOAD_KEY", L"载入密钥", dwLangIdCn);    g_pLangRes->LangResSaveString(L"IDC_BTN_LOAD_KEY", L"Load Key text", dwLangIdEn);//     #define IDC_BTN_DECRYPT                 1004    g_pLangRes->LangResSaveString(L"IDC_BTN_DECRYPT", L"解密", dwLangIdCn);    g_pLangRes->LangResSaveString(L"IDC_BTN_DECRYPT", L"decrypt", dwLangIdEn);//     #define IDC_STATIC_PLAINTEXT            1005    g_pLangRes->LangResSaveString(L"IDC_STATIC_PLAINTEXT", L"明文", dwLangIdCn);    g_pLangRes->LangResSaveString(L"IDC_STATIC_PLAINTEXT", L"plaintext", dwLangIdEn);//    #define IDC_STATIC_CIPHERTEXT           1014    g_pLangRes->LangResSaveString(L"IDC_STATIC_CIPHERTEXT", L"密文", dwLangIdCn);    g_pLangRes->LangResSaveString(L"IDC_STATIC_CIPHERTEXT", L"ciphertext", dwLangIdEn);//     #define IDC_EDIT_PLAINTEXT              1006//     #define IDC_EDIT_OTP_KEY                1007//     #define IDC_EDIT_CIPHERTEXT             1008//     #define IDC_STATIC_KEY                  1009    g_pLangRes->LangResSaveString(L"IDC_STATIC_KEY", L"密钥", dwLangIdCn);    g_pLangRes->LangResSaveString(L"IDC_STATIC_KEY", L"cipher key", dwLangIdEn);//     #define IDC_STATIC_ENCRYPT              1010    g_pLangRes->LangResSaveString(L"IDC_STATIC_ENCRYPT", L"加密", dwLangIdCn);    g_pLangRes->LangResSaveString(L"IDC_STATIC_ENCRYPT", L"encrypt", dwLangIdEn);//     #define IDC_STATIC_DECRYPT              1011    g_pLangRes->LangResSaveString(L"IDC_STATIC_DECRYPT", L"解密", dwLangIdCn);    g_pLangRes->LangResSaveString(L"IDC_STATIC_DECRYPT", L"dncrypt", dwLangIdEn);//     #define IDC_STATIC_PROG_INFO            1012    g_pLangRes->LangResSaveString(L"IDC_STATIC_PROG_INFO", L"加解密算法UI", dwLangIdCn);    g_pLangRes->LangResSaveString(L"IDC_STATIC_PROG_INFO", L"cipher Algorithm ui", dwLangIdEn);//     #define IDC_STATIC_COPY_RIGHT           1013    g_pLangRes->LangResSaveString(L"IDC_STATIC_COPY_RIGHT", L"copyleft 2013", dwLangIdCn);    g_pLangRes->LangResSaveString(L"IDC_STATIC_COPY_RIGHT", L"copyleft 2013", dwLangIdEn);    /// 系统内建的ID    // IDOK    g_pLangRes->LangResSaveString(L"IDOK", L"确定", dwLangIdCn);    g_pLangRes->LangResSaveString(L"IDOK", L"OK", dwLangIdEn);#endif}CLanguageRes * LangResGet(){    return g_pLangRes;}void ReleaseRes(){    SAFE_DELETE(g_pLangRes);}

Demo中选择语言是编译时刻指定, e.g. 中文环境中使用英文UI.

实际应用时, 是用户选择多国语言菜单后, 执行

CLanguageRes::UseLanguageId(false, xx_languageId);

调试的时候, 发现有几百字节的内存泄漏, 在工程中加入了VLD, 超好用, 在Debug模式下运行一次, 退出后, 就看到哪泄漏了.

VLD工程是开源的 , .

转载地址:https://lostspeed.blog.csdn.net/article/details/8521992 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:debian - 自启动的例子
下一篇:reset debian7 local root password

发表评论

最新留言

逛到本站,mark一下
[***.202.152.39]2024年04月15日 10时56分00秒