MFC多语言方式——wxWidget多语言移植

时间:2022-11-25 15:55:34

此前移植了wxWidget代码,将其编写成动态库,可用在MFC中!

相关代码在博客资源中,与文章同名。

 

1.移植wxWidget部分代码,生成DLL。

在wxLocale.h中定义了宏_(),目的是为了使用Poedit可以将_()中包含的内容搜索出来,利用了wxWidget制作多语言的方便。

http://d.download.csdn.net/down/3418287/songly1 

 

2.将生成的wxLocale.h,LanguageLib.lib,LanguageLib.dll加入。

 

3.在app头文件中包含#include "wxLocale.h"

并在app类中定义

void SelectLanguage(int nLanguage);
wxLocale* m_local;

 

4.在app的cpp文件中

void CMultiLanguageWxApp::SelectLanguage(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;
  case wxLocale::wxLANGUAGE_CHINESE_*:
   bRet = m_local->AddCatalog(_T("Languages//zh.mo"));
   break;

  }
  if(!bRet)
  {
   AfxMessageBox(_("Language package is not find!"));
  }
 }
}

 

5.菜单内容多语言

 

在MainFraim中增加函数,函数中所有需要转换的字符用_();(记住不是_T()哟)。

ChangeLanguage()
{
 CMenu* pSubMenu;
 CMenu* pMenu = GetMenu();
 if(pMenu != NULL)
 {
  pMenu->ModifyMenu(0,MF_BYPOSITION,0,_("文件(&F)"));
  pSubMenu = pMenu->GetSubMenu(0);
  if(pSubMenu != NULL)
  {
   pSubMenu->ModifyMenu(ID_FILE_NEW,MF_BYCOMMAND,ID_FILE_NEW,_("新建(&N)/tCtrl+N"));
   pSubMenu->ModifyMenu(ID_FILE_OPEN,MF_BYCOMMAND,ID_FILE_OPEN,_("打开(&O).../tCtrl+O"));
   pSubMenu->ModifyMenu(ID_FILE_SAVE,MF_BYCOMMAND,ID_FILE_SAVE,_("保存(&S)/tCtrl+S"));
   pSubMenu->ModifyMenu(ID_FILE_SAVE_AS,MF_BYCOMMAND,ID_FILE_SAVE_AS,_("另存为(&A)..."));
   pSubMenu->ModifyMenu(ID_FILE_PRINT,MF_BYCOMMAND,ID_FILE_PRINT,_("打印(&P).../tCtrl+P"));
   pSubMenu->ModifyMenu(ID_FILE_PRINT_PREVIEW,MF_BYCOMMAND,ID_FILE_PRINT_PREVIEW,_("打印预览(&V)"));
   pSubMenu->ModifyMenu(ID_FILE_PRINT_SETUP,MF_BYCOMMAND,ID_FILE_PRINT_SETUP,_("打印设置(&R)..."));
   pSubMenu->ModifyMenu(9,MF_BYPOSITION, 0, _("最近的文件"));  //byPosition的方式
   //pSubMenu->ModifyMenu(ID_FILE_MRU_FILE1,MF_BYCOMMAND,ID_FILE_MRU_FILE1,_("最近的文件"));
   pSubMenu->ModifyMenu(ID_APP_EXIT,MF_BYCOMMAND,ID_APP_EXIT,_("退出(Q).../tCtrl+Q"));
  }

  pMenu->ModifyMenu(1,MF_BYPOSITION,1,_("编辑(&E)"));
  pSubMenu = pMenu->GetSubMenu(1);
  if(pSubMenu != NULL)
  {
   pSubMenu->ModifyMenu(ID_EDIT_UNDO, MF_BYCOMMAND, ID_EDIT_UNDO, _("撤消(&U)/tCtrl+Z"));
   pSubMenu->ModifyMenu(ID_EDIT_CUT, MF_BYCOMMAND, ID_EDIT_CUT, _("剪切(&T)/tCtrl+X"));
   pSubMenu->ModifyMenu(ID_EDIT_COPY, MF_BYCOMMAND, ID_EDIT_COPY, _("复制(&C)/tCtrl+C"));
   pSubMenu->ModifyMenu(ID_EDIT_PASTE, MF_BYCOMMAND, ID_EDIT_PASTE, _("粘贴(&P)/tCtrl+V"));
  }

  pMenu->ModifyMenu(2,MF_BYPOSITION,2,_("视图(&V)"));
  pSubMenu = pMenu->GetSubMenu(2);
  if(pSubMenu != NULL)
  {
   pSubMenu->ModifyMenu(ID_VIEW_TOOLBAR,MF_BYCOMMAND,ID_VIEW_TOOLBAR,_("工具栏(&T)"));
   pSubMenu->ModifyMenu(ID_VIEW_STATUS_BAR,MF_BYCOMMAND,ID_VIEW_STATUS_BAR,_("状态栏(&S)"));
  }

  pMenu->ModifyMenu(3,MF_BYPOSITION,3,_("帮助(&H)"));
  pSubMenu = pMenu->GetSubMenu(3);
  if(pSubMenu != NULL)
  {
   pSubMenu->ModifyMenu(ID_APP_ABOUT,MF_BYCOMMAND,ID_APP_ABOUT,_("关于 MultiLanguageWx(&)..."));
   pSubMenu->ModifyMenu(ID_LANGUAGE_ENGLISH,MF_BYCOMMAND,ID_LANGUAGE_ENGLISH,_("英语"));
   pSubMenu->ModifyMenu(ID_LANGUAGE_CHINESE,MF_BYCOMMAND,ID_LANGUAGE_CHINESE,_("简体中文"));
  }
 }
 DrawMenuBar();
}

 

6.Toolbar提示多语言实现

Mainframe头文件手动加载消息afx_msg BOOL OnToolTipText(UINT, NMHDR *pNMHDR, LRESULT *pResult);

 

在Map如下

ON_COMMAND(ID_LANGUAGE_ENGLISH, &CMainFrame::OnLanguageEnglish)
 ON_COMMAND(ID_LANGUAGE_CHINESE, &CMainFrame::OnLanguageChinese)

 

函数实现

BOOL CMainFrame::OnToolTipText(UINT, NMHDR *pNMHDR, LRESULT*   pResult)  
{  

 ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);  

 //   UNICODE消息  
 TOOLTIPTEXTA *pTTTA = (TOOLTIPTEXTA*)pNMHDR;  
 TOOLTIPTEXTW *pTTTW = (TOOLTIPTEXTW*)pNMHDR;  

 CString strTipText;  
 UINT    nID = (UINT)pNMHDR->idFrom;  

 switch (nID)
 {
 case ID_FILE_NEW:
  strTipText = _("新建(N)/tCtrl+N");
  break;
 case ID_FILE_OPEN:
  strTipText = _("打开(O).../tCtrl+O");
  break;
 case ID_FILE_SAVE:
  strTipText = _("保存(S)/tCtrl+S");
  break;
 case ID_EDIT_CUT:
  strTipText = _("剪切(&T)/tCtrl+X");
  break; ;
 case ID_EDIT_COPY:
  strTipText = _("复制(&C)/tCtrl+C");
  break;
 case ID_EDIT_PASTE:
  strTipText = _("粘贴(&P)/tCtrl+V");
  break;
 case ID_FILE_PRINT:
  strTipText = _("打印(&P).../tCtrl+P");
  break;
 case ID_APP_ABOUT:
  strTipText = _("关于 MultiLanguageWx(&)...");
  break;
 default:
  strTipText = _("");
  break;

 }


#ifndef _UNICODE
 if (pNMHDR->code == TTN_NEEDTEXTA)
 {
  lstrcpyn(pTTTA->szText, strTipText, sizeof(pTTTA->szText));
 }
 else
 {
  _mbstowcsz(pTTTW->szText, strTipText, sizeof(pTTTW->szText));
 }
#else
 if (pNMHDR->code == TTN_NEEDTEXTA)
 {
  _wcstombsz(pTTTA->szText, strTipText,sizeof(pTTTA->szText));
 }
 else
 {
  lstrcpyn(pTTTW->szText, strTipText, sizeof(pTTTW->szText));
 }
#endif


 *pResult   =   0;  

 //   使工具条提示窗口在最上面  
 ::SetWindowPos(pNMHDR->hwndFrom,   HWND_TOP,   0,   0,   0,   0,SWP_NOACTIVATE|  
  SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER);    
 return   TRUE;  

}

 

7.about对话框的多语言

这个简单,直接加消息在OnInitDialog中重写。该例子只是改了标题因此只有一句话。

SetWindowText(_("关于 MultiLanguageWx(&)..."));

注意:如果是复杂对话框,需要对每个控件进行setText,而且static控件需要自定义ID。如果是嵌在View类的对话框,就是需要在每个对话框中添加一个setText的函数,该函数将所有控件重新设置。还需要在创建对话框类时创建全局的对象,每次切换语言的时候用全局的对话框类对象调用之前写的setText函数对每个控件重新设置。

 

8.最关键的是生成.mo文件

每种语言生成一个mo文件。如en.mo和zhcn.mo.

需要学会poedit的使用方法。(具体到网上查找,有详细的指导)

安装后,新建项目。设置如下图。

MFC多语言方式——wxWidget多语言移植

 

路径要是众多cpp文件目录下。而且保存生成的po文件也要在该目录下。

MFC多语言方式——wxWidget多语言移植

 

 

最后导入后,对每个自动查找到的项目进行设置。每个版本要设置一次,生成一个mo。然后对mo重命名为en.mo或zhch.mo。

MFC多语言方式——wxWidget多语言移植

 

 

以上就完成了多语言功能。详细的可以看例子。

http://download.csdn.net/source/3343701

 

注意:1.vc6.0的时候需要将工程设置改成Use Unicode Character Set。(待验证)

         2.此方法最麻烦的是对poedit的初次使用,但是一旦学会了,你会发现poedit的强大之处。不解释。