标签:
关于MFC多语言环境的实现,其本质其实只是下面的几句代码
#define CHINESE 0
#define ENGLISH 1
void CMFCMultiLanguageDemoDlg::LanguageChange(int nLanguage)
{
CMenu* pSubMenu;
CMenu* pMenu = GetMenu();
switch (nLanguage)
{
case CHINESE:
//菜单字符修改
pMenu->ModifyMenu(0, MF_BYPOSITION, 0, L"文件(F)");
pSubMenu = pMenu->GetSubMenu(0);
pSubMenu->ModifyMenu(ID_NEWFILE, MF_BYCOMMAND, ID_NEWFILE, L"新建(N)");
pMenu->ModifyMenu(1, MF_BYPOSITION, 0, L"编辑(E)");
pSubMenu = pMenu->GetSubMenu(1);
pSubMenu->ModifyMenu(ID_EDIT, MF_BYCOMMAND, ID_EDIT, L"撤销(U)");
DrawMenuBar();
//按钮字符修改
GetDlgItem(IDC_BUTTON_CHINESE)->SetWindowTextW(L"中文");
GetDlgItem(IDC_BUTTON_ENGLISH)->SetWindowTextW(L"英文");
break;
case ENGLISH:
//菜单字符修改
pMenu->ModifyMenu(0, MF_BYPOSITION, 0, L"File(F)");
pSubMenu = pMenu->GetSubMenu(0);
pSubMenu->ModifyMenu(ID_NEWFILE, MF_BYCOMMAND, ID_NEWFILE, L"New(N)");
pSubMenu = pMenu->GetSubMenu(0);
pMenu->ModifyMenu(1, MF_BYPOSITION, 0, L"Edit(E)");
pSubMenu = pMenu->GetSubMenu(1);
pSubMenu->ModifyMenu(ID_EDIT, MF_BYCOMMAND, ID_EDIT, L"Undo(U)");
DrawMenuBar();
//按钮字符修改
GetDlgItem(IDC_BUTTON_CHINESE)->SetWindowTextW(L"Chinese");
GetDlgItem(IDC_BUTTON_ENGLISH)->SetWindowTextW(L"English");
break;
}
}
void CMFCMultiLanguageDemoDlg::OnBnClickedButtonChinese()
{
LanguageChange(CHINESE);
}
void CMFCMultiLanguageDemoDlg::OnBnClickedButtonEnglish()
{
LanguageChange(ENGLISH);
}
它所实现的效果如下:
1.翻译一种语言就要写一个case,如果有1000项要改,适配三种语言,就要写3000+行来改。
2.需要给翻译人员源代码,或者想办法暴露接口给他们,分工复杂,不符合现在程序设计的分块化理念。
那么,问题就来了,怎么做才能回避掉上面的问题呢?
答案是将上面的代码改成如下的形式(下面是伪代码):
#define CHINESE 0
#define ENGLISH 1
void CMFCMultiLanguageDemoDlg::LanguageChange(int nLanguage)
{
switch (nLanguage)
{
case CHINESE:
mylanguage.SelectLanguage=loadlanguagefile("CHINESE.mo");//读取语言包文件
break;
case ENGLISH:
mylanguage.SelectLanguage=loadlanguagefile("ENGLISH.mo");//读取语言包文件
break;
}
//根据语言包翻译控件字符,Translation函数以中文字符为输入参数,返回翻译完的字符给控件
CMenu* pSubMenu;
CMenu* pMenu = GetMenu();
//菜单字符修改
pMenu->ModifyMenu(0, MF_BYPOSITION, 0, mylanguage.Translation(L"文件(F)"));
pSubMenu = pMenu->GetSubMenu(0);
pSubMenu->ModifyMenu(ID_NEWFILE, MF_BYCOMMAND, ID_NEWFILE, mylanguage.Translation(L"新建(N)"));
pMenu->ModifyMenu(1, MF_BYPOSITION, 0, mylanguage.Translation("编辑(E)"));
pSubMenu = pMenu->GetSubMenu(1);
pSubMenu->ModifyMenu(ID_EDIT, MF_BYCOMMAND, ID_EDIT, mylanguage.Translation(L"撤销(U)"));
DrawMenuBar();
//按钮字符修改
GetDlgItem(IDC_BUTTON_CHINESE)->SetWindowTextW(mylanguage.Translation(L"中文"));
GetDlgItem(IDC_BUTTON_ENGLISH)->SetWindowTextW(mylanguage.Translation(L"英文"));
}
void CMFCMultiLanguageDemoDlg::OnBnClickedButtonChinese()
{
LanguageChange(CHINESE);
}
void CMFCMultiLanguageDemoDlg::OnBnClickedButtonEnglish()
{
LanguageChange(ENGLISH);
}
在这种形式下,上面的两个问题就解决了:
1.每增加一种需要翻译的语言,只需制作一个相应的文件与之对应,且在代码里增加对应的文件读取接口即可。
2.该语言文件可以直接交给翻译人员制作。
那么,下面我们来真正的实现它。
按照上面伪代码的做法,我们可以自己写一个类来实现,但是那样比较麻烦。因此,我们借助这篇文章的帮忙,无视掉他繁琐乏味的文字,直接去下载他的工程,找到里面即犀利又有用的dll文件夹。打开文件夹,看到里面是一个动态链接库的三个文件,这就是我们要实现的这个类。把他配起来:
1.把三个文件拷贝到我们自己的工程目录下。
2.项目->属性->配置属性->链接器->输入->附加依赖项->LanguageLib.lib
3.解决方案资源管理器项目名称上面右键->添加->现有项->wxLocale.h
好了,我们只需要引用这个类就行了。为了有更好的兼容性,我们把这个类再封装一下,代码如下:
class mylanguage
{
public:
wxLocale* m_local;
void init(int nLanguage)
{
if (m_local != NULL)
m_local->Release();
m_local = CreateObject(nLanguage);
if (m_local != NULL)
{
//选择语言包
bool bRet = false;
switch (nLanguage)
{
case wxLocale::wxLANGUAGE_ENGLISH:
bRet = m_local->AddCatalog(_T("Languages\\en.mo"));
break;
case wxLocale::wxLANGUAGE_CHINESE_SIMPLIFIED:
bRet = m_local->AddCatalog(_T("Languages\\zhcn.mo"));
break;
}
if (!bRet)
{
AfxMessageBox(_("Language package is not find!"));
}
}
}
};
然后我们把这个类利用起来,声明一个它的实例m_languageobj,然后改写主代码如下:
void CMFCMultiLanguageDemoDlg::LanguageChange(int nLanguage)
{
m_languageobj.init(nLanguage);
CMenu* pSubMenu;
CMenu* pMenu = GetMenu();
//菜单字符修改
pMenu->ModifyMenu(0, MF_BYPOSITION, 0, _("文件(F)"));
pSubMenu = pMenu->GetSubMenu(0);
pSubMenu->ModifyMenu(ID_NEWFILE, MF_BYCOMMAND, ID_NEWFILE, _("新建(N)"));
pMenu->ModifyMenu(1, MF_BYPOSITION, 0, _("编辑(E)"));
pSubMenu = pMenu->GetSubMenu(1);
pSubMenu->ModifyMenu(ID_EDIT, MF_BYCOMMAND, ID_EDIT, _("撤销(U)"));
DrawMenuBar();
//按钮字符修改
GetDlgItem(IDC_BUTTON_CHINESE)->SetWindowTextW(_("中文"));
GetDlgItem(IDC_BUTTON_ENGLISH)->SetWindowTextW(_("英文"));
}
void CMFCMultiLanguageDemoDlg::OnBnClickedButtonChinese()
{
LanguageChange(wxLocale::wxLANGUAGE_CHINESE_SIMPLIFIED);
}
void CMFCMultiLanguageDemoDlg::OnBnClickedButtonEnglish()
{
LanguageChange(wxLocale::wxLANGUAGE_ENGLISH);
}
完成,编译运行,找不到语言包,囧。。。。。。
我们需要做这个工程相应的语言包。用poedit,下载(我下载的是官网最新版本1.8.7),安装,然后
1.文件->新建->中文->确定->保存(放到工程主路径下面,就是放源文件.h和.cpp的那个路径下)
#define _(s) zijishixiandehanshu(s)
标签:
原文地址:http://blog.csdn.net/weixinhum/article/details/51202263