HINSTANCE hinstance = ::LoadLibrary("resourceeng.dll" );
if( hinstance == NULL ) return;
::AfxSetResourceHandle( hinstance );
但这样好象不行,怎么做?
3 个解决方案
#1
你可以为每一种语言建立一个资源动态库,在运行过程中根据不同的选择动态装入合适的动态库,并且所有的界面元素都从这个动态库中装入就行了——上面不应该有问题吧
#2
我刚完成一个国际化的网络应用程序,我是这样做的.
1:思路,UI的国际化分为两个部分,菜单和其它资源.
2:国际化的工作也就分为两个部分,菜单资源的ReLoad和其它UI(文本)的Reload.
3:菜单的ReLoad使用下面的函数(我的风格尽量不用MFC),菜单可以直接在资源文件.rc
中编辑.
BOOL ChangeMenu()
{
//////////////////////////////////////////////
//////It's difficult to change the menu///////
/////It's important to set m_hMenuDefault/////
/////to hNewMenu.First,I haven't do this,/////
/////error will occur whenever the window/////
/////be closed.The reason is,memory address///
////will change if HMENU changed.Yet,I can////
///////not find any information about ////////
///////m_hMenuDefault in Help document////////
HINSTANCE hInst;
HRSRC hRc;
HGLOBAL hGl;
WORD lang;
MENUTEMPLATE* lpTemp;
HMENU hOldMenu,hNewMenu;
lang=GetCurrentLanguage();
hInst=AfxGetResourceHandle();
hRc=::FindResourceEx(hInst,RT_MENU,
MAKEINTRESOURCE(IDR_MAINFRAME),lang);
if(hRc==NULL)
return FALSE;
hGl=::LoadResource(hInst,hRc);
if(hGl==NULL)
return FALSE;
lpTemp=(MENUTEMPLATE *)::LockResource(hGl);
if(lpTemp==NULL){
::FreeResource(hGl);
return FALSE;
}
hNewMenu=::LoadMenuIndirect(lpTemp);
if(hNewMenu==NULL){
::FreeResource(hGl);
::UnlockResource(hGl);
return FALSE;
}
hOldMenu=::GetMenu(m_hWnd);
if(hOldMenu)
::DestroyMenu(hOldMenu);
::SetMenu(m_hWnd,hNewMenu);
m_hMenuDefault=hNewMenu;
::FreeResource(hGl);
::UnlockResource(hGl);
return TRUE;
}
4:其它资源的Reload基于下面的思路:在资源文件.rc中全是英文资源,在textres.*文件中实现资源的Reload,看了下面的两个文件你应该会明白.
*****************textres.h****************************
#ifndef _TEXTRES_H
#define _TEXTRES_H
#include "resource.h"
typedef struct _text_item
{
UINT resID;
LPCTSTR text;
} TEXT_ITEM,FAR* LPTEXT_ITEM;
typedef struct _lang_pointer
{
WORD langID;
LPTEXT_ITEM lpTextItem;
} LANG_POINTER,FAR* LPLANG_POINTER;
void SetCurrentLanguage(WORD langID);
WORD GetCurrentLanguage();
int LoadTextByID(UINT resID,LPTSTR string,int maxsize);
//maxsize should include the terminating null character
#endif
*************************************************************
#include "StdAfx.h"
#include "textres.h"
int gCurrentIndex;
//////////////////////////////
/////English Text Resource////
////Retrieve from .rc file////
TEXT_ITEM usaTextItem[]={
{0,NULL}
};
///////////////////////////////////
////Chinese Simplified Resource////
///////Retrive until resID==0//////
TEXT_ITEM chsTextItem[]={
{IDS_GAMP_APPTITLE, "MailToFax 1.0"},
{IDS_FILTER, "´«ÕæÎļþ|*.g3|ËùÓÐÎļþ|*.*|"},
{IDS_GAMP_BROWSE, "ä¯ÀÀ"},
{IDS_GAMP_NAMEANDFAX, "Ãû³ÆºÍ´«ÕæºÅ:"},
{IDS_GAMP_SUBJECT, "Ö÷Ìâ"},
{IDS_GAMP_SEND, "·¢ËÍ"},
{IDS_GAMP_FILENAME, "ÎļþÃû³Æ:"},
{IDS_GAMP_COMMBOOK, "ͨѶ²¾"},
{IDS_GAMP_OK, "È·¶¨"},
{IDS_GAMP_CANCEL, "È¡Ïû"},
{IDS_GAMP_NEW, "ÐÂÔö"},
{IDS_GAMP_MODIFY, "ÐÞ¸Ä"},
{IDS_GAMP_DELETE, "ɾ³ý"},
{IDS_GAMP_NAME, "ÐÕÃû"},
{IDS_GAMP_FAXNO, "´«ÕæºÅ"},
{IDS_GAMP_COMPANY, "¹«Ë¾"},
{IDS_GAMP_CANNOTBEEMPTY, " ²»ÄÜΪ¿Õ."},
{IDS_GAMP_MUSTBENUMERIC, " ±ØÐëÊÇÊý×Ö."},
{IDS_GAMP_CANNOTBEZERO, " ²»ÄÜΪÁã."},
{IDS_GAMP_NODATAREMAINED, "ÒѾ­Ã»ÓÐÊý¾ÝÁË."},
{IDS_GAMP_NOROWSELECTED, "ÇëÏÈÑ¡ÔñÒ»ÐÐÊý¾Ý."},
{IDS_GAMP_DATABASEERROR, "Êý¾Ý¿â·ÃÎʳö´í."},
{IDS_GAMP_DATAEXIST, "Êý¾ÝÒѾ­´æÔÚ."},
{IDS_GAMP_ORIGCOPY, "Ç빺ÂòÕý°æÈí¼þ."},
{IDS_GAMP_FINDBY, "Ìõ¼þ²éѯ"},
{IDS_GAMP_QUERY, "²éѯ"},
{IDS_GAMP_SELECTED, "ÒѾ­Ñ¡Ôñ"},
{IDS_GAMP_NEXT, "ÏÂÒ»Ïî"},
{IDS_GAMP_NAMEFAXNONOTMATCH, "±ØÐë°´´Ë¸ñʽÊäÈë:\nName-FaxNo."},
{IDS_GAMP_LENGTHTOOLONG, "Ì«³¤ÁË."},
{IDS_GAMP_NOFOUNDDATA, "ûÓз¢ÏÖÆ¥ÅäµÄÏîÄ¿."},
{IDS_GAMP_USERID, "Óû§IDºÅ"},
{IDS_GAMP_PASSWORD, "Óû§¿ÚÁî"},
{IDS_GAMP_EMAILADDRESS, "»ØÓ¦EmailµØÖ·"},
{IDS_GAMP_GATEWAY, "Íø¹ØEmailµØÖ·"},
{IDS_GAMP_SERVER, "SMTP ·þÎñÆ÷"},
{IDS_GAMP_PORT, "SMTP ¶Ë¿Ú"},
{IDS_GAMP_FAXNAME, "´«Õæ»úÆ÷Ãû"},
{IDS_GAMP_SYSCONFIG, "ϵͳÉèÖÃ"},
{IDS_GAMP_INVALIDVALUE, " ÎÞЧµÄÊý¾Ý."},
{IDS_GAMP_BETWEEN9999, " ±ØÐëÏÞÖÆÔÚ1-9999."},
{IDS_GAMP_OPENFILEERROR, "´ò¿ªÎļþʱ³ö´í."},
{IDS_GAMP_FAILTOOLBAR, "´´½¨¹¤¾ßÌõʱ³ö´í."},
{IDS_GAMP_SETSYSCONFIGFIRST, "ÇëÏÈÉèÖÃϵͳ²ÎÊý."},
{IDS_STATUS_SMTPFROM, "·¢ËÍ SMTP from µØÖ·"},
{IDS_STATUS_SMTPTO, "·¢ËÍ SMTP to µØÖ·"},
{IDS_STATUS_TRANSFERING, "´«ÊäÕýÎÄÊý¾Ý..."},
{IDS_STATUS_GETPORT, "¼ìË÷ TCP/IP ÍøÂç¶Ë¿Ú..."},
{IDS_STATUS_RETRIVEADDRESS, "¼ìË÷ internet µØÖ·..."},
{IDS_STATUS_GETPROTOCOL, "¼ìË÷ÍøÂçЭÒé..."},
{IDS_STATUS_CREATESOCKET, "´´½¨ socket..."},
{IDS_STATUS_ESTABLISHCONNECT, "½¨Á¢ÍøÂçÁ¬½Ó..."},
{IDS_STATUS_GETHOSTNAME, "¼ìË÷Ö÷»úÃû³Æ..."},
{IDS_STATUS_CONNECTTOTCP, "Óë TCP ½¨Á¢Á¬½Ó..."},
{IDS_STATUS_SENDHELO, "·¢ËÍ HELO ÐÅÏ¢..."},
{IDS_STATUS_REPLYHELO, "½ÓÊÕ HELO µÄ»ØÓ¦..."},
{IDS_STATUS_LASTTASK, "×îºóµÄÈÎÎñ..."},
{IDS_STATUS_TRANFORMOK, "ÍøÂç´«Êä³É¹¦."},
{IDS_STATUS_TRANSFORMERROR, "ÍøÂç´«Êäʧ°Ü."},
{IDS_GAMP_READG3ERROR, "¶Á .g3 Îļþʱ³ö´í£¬¿ÉÄÜËü²»ÊÇÕýÈ·µÄ¸ñʽ."},
{IDS_GAMP_FIRSTPAGE, "ËüÒѾ­ÊǵÚÒ»Ò³ÁË."},
{IDS_GAMP_LASTPAGE, "ËüÒѾ­ÊÇ×îºóÒ»Ò³ÁË."},
{IDS_GAMP_PAGE, "Ò³ºÅ"},
{IDS_GAMP_THREADLIST, "ÔËÐеĴ«ÊäÏß³Ì"},
{IDS_GAMP_CURSTATUS, "µ±Ç°×´Ì¬"},
{IDS_GAMP_TERMINATE, "ÖÕÖ¹"},
{IDS_GAMP_MEMORYERROR, "ÄÚ´æ³öÏÖÑÏÖØ´íÎó!"},
{0,NULL}
};
///////////////////////////////////
///Chinese Traditional Resource////
///////Retrive until resID==0//////
TEXT_ITEM twnTextItem[]={
{IDS_GAMP_APPTITLE, "MailToFax 1.0"},
{IDS_FILTER, "‚÷ÕæÎļþ|*.g3|ËùÓÐÎļþ|*.*|"},
{IDS_GAMP_BROWSE, "žgÓ["},
{IDS_GAMP_NAMEANDFAX, "Ãû·QºÍ‚÷ÕæÌ–:"},
{IDS_GAMP_SUBJECT, "Ö÷î}"},
{IDS_GAMP_SEND, "°lËÍ"},
{IDS_GAMP_FILENAME, "ÎļþÃû·Q:"},
{IDS_GAMP_COMMBOOK, "ͨӍ²¾"},
{IDS_GAMP_OK, "´_¶¨"},
{IDS_GAMP_CANCEL, "È¡Ïû"},
{IDS_GAMP_NEW, "ÐÂÔö"},
{IDS_GAMP_MODIFY, "ÐÞ¸Ä"},
{IDS_GAMP_DELETE, "„h³ý"},
{IDS_GAMP_NAME, "ÐÕÃû"},
{IDS_GAMP_FAXNO, "‚÷ÕæÌ–"},
{IDS_GAMP_COMPANY, "¹«Ë¾"},
{IDS_GAMP_CANNOTBEEMPTY, " ²»ÄÜ ‘¿Õ."},
{IDS_GAMP_MUSTBENUMERIC, " ±ØíšÊÇ”µ×Ö."},
{IDS_GAMP_CANNOTBEZERO, " ²»ÄÜ ‘Áã."},
{IDS_GAMP_NODATAREMAINED, "Òѽ››]ÓДµ“þÁË."},
{IDS_GAMP_NOROWSELECTED, "ÕˆÏÈßx“ñÒ»ÐДµ“þ."},
{IDS_GAMP_DATABASEERROR, "”µ“þŽìÔL†–³öåe."},
{IDS_GAMP_DATAEXIST, "”µ“þÒѽ›´æÔÚ."},
{IDS_GAMP_ORIGCOPY, "ՈُÙIÕý°æÜ›¼þ."},
{IDS_GAMP_FINDBY, "—l¼þ²éÔƒ"},
{IDS_GAMP_QUERY, "²éÔƒ"},
{IDS_GAMP_SELECTED, "Òѽ›ßx“ñ"},
{IDS_GAMP_NEXT, "ÏÂÒ»í—"},
{IDS_GAMP_NAMEFAXNONOTMATCH, "±Øíš°´´Ë¸ñʽݔÈë:\nName-FaxNo."},
{IDS_GAMP_LENGTHTOOLONG, "Ì«éLÁË."},
{IDS_GAMP_NOFOUNDDATA, "›]Óаl¬FÆ¥ÅäµÄí—Ä¿."},
{IDS_GAMP_USERID, "ÓÑôIDÌ–"},
{IDS_GAMP_PASSWORD, "ÓÑô¿ÚÁî"},
{IDS_GAMP_EMAILADDRESS, "»Ø‘ªEmailµØÖ·"},
{IDS_GAMP_GATEWAY, "¾WêPEmailµØÖ·"},
{IDS_GAMP_SERVER, "SMTP ·þ„ÕÆ÷"},
{IDS_GAMP_PORT, "SMTP ¶Ë¿Ú"},
{IDS_GAMP_FAXNAME, "‚÷Õæ™CÆ÷Ãû"},
{IDS_GAMP_SYSCONFIG, "ϵ½yÔOÖÃ"},
{IDS_GAMP_INVALIDVALUE, " ŸoЧµÄ”µ“þ."},
{IDS_GAMP_BETWEEN9999, " ±ØíšÏÞÖÆÔÚ1-9999."},
{IDS_GAMP_OPENFILEERROR, "´òé_Îļþ•r³öåe."},
{IDS_GAMP_FAILTOOLBAR, "„“½¨¹¤¾ß—l•r³öåe."},
{IDS_GAMP_SETSYSCONFIGFIRST, "ÕˆÏÈÔOÖÃϵ½y…¢”µ."},
{IDS_STATUS_SMTPFROM, "°lËÍ SMTP from µØÖ·"},
{IDS_STATUS_SMTPTO, "°lËÍ SMTP to µØÖ·"},
{IDS_STATUS_TRANSFERING, "‚÷Ý”ÕýÎÄ”µ“þ..."},
{IDS_STATUS_GETPORT, "™zË÷ TCP/IP ¾W½j¶Ë¿Ú..."},
{IDS_STATUS_RETRIVEADDRESS, "™zË÷ internet µØÖ·..."},
{IDS_STATUS_GETPROTOCOL, "™zË÷¾W½j…f×h..."},
{IDS_STATUS_CREATESOCKET, "„“½¨ socket..."},
{IDS_STATUS_ESTABLISHCONNECT, "½¨Á¢¾W½jßB½Ó..."},
{IDS_STATUS_GETHOSTNAME, "™zË÷Ö÷™CÃû·Q..."},
{IDS_STATUS_CONNECTTOTCP, "Åc TCP ½¨Á¢ßB½Ó..."},
{IDS_STATUS_SENDHELO, "°lËÍ HELO ÐÅÏ¢..."},
{IDS_STATUS_REPLYHELO, "½ÓÊÕ HELO µÄ»Ø‘ª..."},
{IDS_STATUS_LASTTASK, "×îááµÄÈ΄Õ..."},
{IDS_STATUS_TRANFORMOK, "¾W½j‚÷Ý”³É¹¦."},
{IDS_STATUS_TRANSFORMERROR, "¾W½j‚÷ݔʧ”¡."},
{IDS_GAMP_READG3ERROR, "×x .g3 Îļþ•r³öåe£¬¿ÉÄÜËü²»ÊÇÕý´_µÄ¸ñʽ."},
{IDS_GAMP_FIRSTPAGE, "ËüÒѽ›ÊǵÚÒ»í“ÁË."},
{IDS_GAMP_LASTPAGE, "ËüÒѽ›ÊÇ×îááÒ»í“ÁË."},
{IDS_GAMP_PAGE, "í“Ì–"},
{IDS_GAMP_THREADLIST, "ß\ÐеĂ÷Ý”¾€³Ì"},
{IDS_GAMP_CURSTATUS, "®”Ç° î‘B"},
{IDS_GAMP_TERMINATE, "½KÖ¹"},
{IDS_GAMP_MEMORYERROR, "ƒÈ´æ³ö¬F‡ÀÖØåeÕ`!"},
{0,NULL}
};
///////////////////////////////////////////
////////language text item pointer/////////
LANG_POINTER langPointer[]={
{MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),&usaTextItem[0]},
{MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),&chsTextItem[0]},
{MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_TRADITIONAL),&twnTextItem[0]},
{0,NULL}
};
void SetCurrentLanguage(WORD langID)
{
int i=0;
while(1){
if(langPointer[i].langID==0){
gCurrentIndex=0;//English default even if error occurred
return;
}
if(langPointer[i].langID==langID)
break;
i++;
}
gCurrentIndex=i;
}
WORD GetCurrentLanguage()
{
return langPointer[gCurrentIndex].langID;
}
int LoadTextByID(UINT resID,LPTSTR string,int maxsize)
{
if(maxsize<=0)
return maxsize;
CString str;
LPTEXT_ITEM lpItem;
int copylength;
copylength=0;
if(gCurrentIndex==0){//English
str.LoadString(resID);
copylength=min(str.GetLength(),maxsize-1);
lstrcpy(string,str);
}
else{
lpItem=langPointer[gCurrentIndex].lpTextItem;
while(1){
if(lpItem->resID==0)
break;//it will never occur
if(lpItem->resID==resID){
copylength=min(lstrlen(lpItem->text),maxsize-1);
lstrcpy(string,lpItem->text);
break;
}
lpItem++;
}
}
return copylength;
};
1:思路,UI的国际化分为两个部分,菜单和其它资源.
2:国际化的工作也就分为两个部分,菜单资源的ReLoad和其它UI(文本)的Reload.
3:菜单的ReLoad使用下面的函数(我的风格尽量不用MFC),菜单可以直接在资源文件.rc
中编辑.
BOOL ChangeMenu()
{
//////////////////////////////////////////////
//////It's difficult to change the menu///////
/////It's important to set m_hMenuDefault/////
/////to hNewMenu.First,I haven't do this,/////
/////error will occur whenever the window/////
/////be closed.The reason is,memory address///
////will change if HMENU changed.Yet,I can////
///////not find any information about ////////
///////m_hMenuDefault in Help document////////
HINSTANCE hInst;
HRSRC hRc;
HGLOBAL hGl;
WORD lang;
MENUTEMPLATE* lpTemp;
HMENU hOldMenu,hNewMenu;
lang=GetCurrentLanguage();
hInst=AfxGetResourceHandle();
hRc=::FindResourceEx(hInst,RT_MENU,
MAKEINTRESOURCE(IDR_MAINFRAME),lang);
if(hRc==NULL)
return FALSE;
hGl=::LoadResource(hInst,hRc);
if(hGl==NULL)
return FALSE;
lpTemp=(MENUTEMPLATE *)::LockResource(hGl);
if(lpTemp==NULL){
::FreeResource(hGl);
return FALSE;
}
hNewMenu=::LoadMenuIndirect(lpTemp);
if(hNewMenu==NULL){
::FreeResource(hGl);
::UnlockResource(hGl);
return FALSE;
}
hOldMenu=::GetMenu(m_hWnd);
if(hOldMenu)
::DestroyMenu(hOldMenu);
::SetMenu(m_hWnd,hNewMenu);
m_hMenuDefault=hNewMenu;
::FreeResource(hGl);
::UnlockResource(hGl);
return TRUE;
}
4:其它资源的Reload基于下面的思路:在资源文件.rc中全是英文资源,在textres.*文件中实现资源的Reload,看了下面的两个文件你应该会明白.
*****************textres.h****************************
#ifndef _TEXTRES_H
#define _TEXTRES_H
#include "resource.h"
typedef struct _text_item
{
UINT resID;
LPCTSTR text;
} TEXT_ITEM,FAR* LPTEXT_ITEM;
typedef struct _lang_pointer
{
WORD langID;
LPTEXT_ITEM lpTextItem;
} LANG_POINTER,FAR* LPLANG_POINTER;
void SetCurrentLanguage(WORD langID);
WORD GetCurrentLanguage();
int LoadTextByID(UINT resID,LPTSTR string,int maxsize);
//maxsize should include the terminating null character
#endif
*************************************************************
#include "StdAfx.h"
#include "textres.h"
int gCurrentIndex;
//////////////////////////////
/////English Text Resource////
////Retrieve from .rc file////
TEXT_ITEM usaTextItem[]={
{0,NULL}
};
///////////////////////////////////
////Chinese Simplified Resource////
///////Retrive until resID==0//////
TEXT_ITEM chsTextItem[]={
{IDS_GAMP_APPTITLE, "MailToFax 1.0"},
{IDS_FILTER, "´«ÕæÎļþ|*.g3|ËùÓÐÎļþ|*.*|"},
{IDS_GAMP_BROWSE, "ä¯ÀÀ"},
{IDS_GAMP_NAMEANDFAX, "Ãû³ÆºÍ´«ÕæºÅ:"},
{IDS_GAMP_SUBJECT, "Ö÷Ìâ"},
{IDS_GAMP_SEND, "·¢ËÍ"},
{IDS_GAMP_FILENAME, "ÎļþÃû³Æ:"},
{IDS_GAMP_COMMBOOK, "ͨѶ²¾"},
{IDS_GAMP_OK, "È·¶¨"},
{IDS_GAMP_CANCEL, "È¡Ïû"},
{IDS_GAMP_NEW, "ÐÂÔö"},
{IDS_GAMP_MODIFY, "ÐÞ¸Ä"},
{IDS_GAMP_DELETE, "ɾ³ý"},
{IDS_GAMP_NAME, "ÐÕÃû"},
{IDS_GAMP_FAXNO, "´«ÕæºÅ"},
{IDS_GAMP_COMPANY, "¹«Ë¾"},
{IDS_GAMP_CANNOTBEEMPTY, " ²»ÄÜΪ¿Õ."},
{IDS_GAMP_MUSTBENUMERIC, " ±ØÐëÊÇÊý×Ö."},
{IDS_GAMP_CANNOTBEZERO, " ²»ÄÜΪÁã."},
{IDS_GAMP_NODATAREMAINED, "ÒѾ­Ã»ÓÐÊý¾ÝÁË."},
{IDS_GAMP_NOROWSELECTED, "ÇëÏÈÑ¡ÔñÒ»ÐÐÊý¾Ý."},
{IDS_GAMP_DATABASEERROR, "Êý¾Ý¿â·ÃÎʳö´í."},
{IDS_GAMP_DATAEXIST, "Êý¾ÝÒѾ­´æÔÚ."},
{IDS_GAMP_ORIGCOPY, "Ç빺ÂòÕý°æÈí¼þ."},
{IDS_GAMP_FINDBY, "Ìõ¼þ²éѯ"},
{IDS_GAMP_QUERY, "²éѯ"},
{IDS_GAMP_SELECTED, "ÒѾ­Ñ¡Ôñ"},
{IDS_GAMP_NEXT, "ÏÂÒ»Ïî"},
{IDS_GAMP_NAMEFAXNONOTMATCH, "±ØÐë°´´Ë¸ñʽÊäÈë:\nName-FaxNo."},
{IDS_GAMP_LENGTHTOOLONG, "Ì«³¤ÁË."},
{IDS_GAMP_NOFOUNDDATA, "ûÓз¢ÏÖÆ¥ÅäµÄÏîÄ¿."},
{IDS_GAMP_USERID, "Óû§IDºÅ"},
{IDS_GAMP_PASSWORD, "Óû§¿ÚÁî"},
{IDS_GAMP_EMAILADDRESS, "»ØÓ¦EmailµØÖ·"},
{IDS_GAMP_GATEWAY, "Íø¹ØEmailµØÖ·"},
{IDS_GAMP_SERVER, "SMTP ·þÎñÆ÷"},
{IDS_GAMP_PORT, "SMTP ¶Ë¿Ú"},
{IDS_GAMP_FAXNAME, "´«Õæ»úÆ÷Ãû"},
{IDS_GAMP_SYSCONFIG, "ϵͳÉèÖÃ"},
{IDS_GAMP_INVALIDVALUE, " ÎÞЧµÄÊý¾Ý."},
{IDS_GAMP_BETWEEN9999, " ±ØÐëÏÞÖÆÔÚ1-9999."},
{IDS_GAMP_OPENFILEERROR, "´ò¿ªÎļþʱ³ö´í."},
{IDS_GAMP_FAILTOOLBAR, "´´½¨¹¤¾ßÌõʱ³ö´í."},
{IDS_GAMP_SETSYSCONFIGFIRST, "ÇëÏÈÉèÖÃϵͳ²ÎÊý."},
{IDS_STATUS_SMTPFROM, "·¢ËÍ SMTP from µØÖ·"},
{IDS_STATUS_SMTPTO, "·¢ËÍ SMTP to µØÖ·"},
{IDS_STATUS_TRANSFERING, "´«ÊäÕýÎÄÊý¾Ý..."},
{IDS_STATUS_GETPORT, "¼ìË÷ TCP/IP ÍøÂç¶Ë¿Ú..."},
{IDS_STATUS_RETRIVEADDRESS, "¼ìË÷ internet µØÖ·..."},
{IDS_STATUS_GETPROTOCOL, "¼ìË÷ÍøÂçЭÒé..."},
{IDS_STATUS_CREATESOCKET, "´´½¨ socket..."},
{IDS_STATUS_ESTABLISHCONNECT, "½¨Á¢ÍøÂçÁ¬½Ó..."},
{IDS_STATUS_GETHOSTNAME, "¼ìË÷Ö÷»úÃû³Æ..."},
{IDS_STATUS_CONNECTTOTCP, "Óë TCP ½¨Á¢Á¬½Ó..."},
{IDS_STATUS_SENDHELO, "·¢ËÍ HELO ÐÅÏ¢..."},
{IDS_STATUS_REPLYHELO, "½ÓÊÕ HELO µÄ»ØÓ¦..."},
{IDS_STATUS_LASTTASK, "×îºóµÄÈÎÎñ..."},
{IDS_STATUS_TRANFORMOK, "ÍøÂç´«Êä³É¹¦."},
{IDS_STATUS_TRANSFORMERROR, "ÍøÂç´«Êäʧ°Ü."},
{IDS_GAMP_READG3ERROR, "¶Á .g3 Îļþʱ³ö´í£¬¿ÉÄÜËü²»ÊÇÕýÈ·µÄ¸ñʽ."},
{IDS_GAMP_FIRSTPAGE, "ËüÒѾ­ÊǵÚÒ»Ò³ÁË."},
{IDS_GAMP_LASTPAGE, "ËüÒѾ­ÊÇ×îºóÒ»Ò³ÁË."},
{IDS_GAMP_PAGE, "Ò³ºÅ"},
{IDS_GAMP_THREADLIST, "ÔËÐеĴ«ÊäÏß³Ì"},
{IDS_GAMP_CURSTATUS, "µ±Ç°×´Ì¬"},
{IDS_GAMP_TERMINATE, "ÖÕÖ¹"},
{IDS_GAMP_MEMORYERROR, "ÄÚ´æ³öÏÖÑÏÖØ´íÎó!"},
{0,NULL}
};
///////////////////////////////////
///Chinese Traditional Resource////
///////Retrive until resID==0//////
TEXT_ITEM twnTextItem[]={
{IDS_GAMP_APPTITLE, "MailToFax 1.0"},
{IDS_FILTER, "‚÷ÕæÎļþ|*.g3|ËùÓÐÎļþ|*.*|"},
{IDS_GAMP_BROWSE, "žgÓ["},
{IDS_GAMP_NAMEANDFAX, "Ãû·QºÍ‚÷ÕæÌ–:"},
{IDS_GAMP_SUBJECT, "Ö÷î}"},
{IDS_GAMP_SEND, "°lËÍ"},
{IDS_GAMP_FILENAME, "ÎļþÃû·Q:"},
{IDS_GAMP_COMMBOOK, "ͨӍ²¾"},
{IDS_GAMP_OK, "´_¶¨"},
{IDS_GAMP_CANCEL, "È¡Ïû"},
{IDS_GAMP_NEW, "ÐÂÔö"},
{IDS_GAMP_MODIFY, "ÐÞ¸Ä"},
{IDS_GAMP_DELETE, "„h³ý"},
{IDS_GAMP_NAME, "ÐÕÃû"},
{IDS_GAMP_FAXNO, "‚÷ÕæÌ–"},
{IDS_GAMP_COMPANY, "¹«Ë¾"},
{IDS_GAMP_CANNOTBEEMPTY, " ²»ÄÜ ‘¿Õ."},
{IDS_GAMP_MUSTBENUMERIC, " ±ØíšÊÇ”µ×Ö."},
{IDS_GAMP_CANNOTBEZERO, " ²»ÄÜ ‘Áã."},
{IDS_GAMP_NODATAREMAINED, "Òѽ››]ÓДµ“þÁË."},
{IDS_GAMP_NOROWSELECTED, "ÕˆÏÈßx“ñÒ»ÐДµ“þ."},
{IDS_GAMP_DATABASEERROR, "”µ“þŽìÔL†–³öåe."},
{IDS_GAMP_DATAEXIST, "”µ“þÒѽ›´æÔÚ."},
{IDS_GAMP_ORIGCOPY, "ՈُÙIÕý°æÜ›¼þ."},
{IDS_GAMP_FINDBY, "—l¼þ²éÔƒ"},
{IDS_GAMP_QUERY, "²éÔƒ"},
{IDS_GAMP_SELECTED, "Òѽ›ßx“ñ"},
{IDS_GAMP_NEXT, "ÏÂÒ»í—"},
{IDS_GAMP_NAMEFAXNONOTMATCH, "±Øíš°´´Ë¸ñʽݔÈë:\nName-FaxNo."},
{IDS_GAMP_LENGTHTOOLONG, "Ì«éLÁË."},
{IDS_GAMP_NOFOUNDDATA, "›]Óаl¬FÆ¥ÅäµÄí—Ä¿."},
{IDS_GAMP_USERID, "ÓÑôIDÌ–"},
{IDS_GAMP_PASSWORD, "ÓÑô¿ÚÁî"},
{IDS_GAMP_EMAILADDRESS, "»Ø‘ªEmailµØÖ·"},
{IDS_GAMP_GATEWAY, "¾WêPEmailµØÖ·"},
{IDS_GAMP_SERVER, "SMTP ·þ„ÕÆ÷"},
{IDS_GAMP_PORT, "SMTP ¶Ë¿Ú"},
{IDS_GAMP_FAXNAME, "‚÷Õæ™CÆ÷Ãû"},
{IDS_GAMP_SYSCONFIG, "ϵ½yÔOÖÃ"},
{IDS_GAMP_INVALIDVALUE, " ŸoЧµÄ”µ“þ."},
{IDS_GAMP_BETWEEN9999, " ±ØíšÏÞÖÆÔÚ1-9999."},
{IDS_GAMP_OPENFILEERROR, "´òé_Îļþ•r³öåe."},
{IDS_GAMP_FAILTOOLBAR, "„“½¨¹¤¾ß—l•r³öåe."},
{IDS_GAMP_SETSYSCONFIGFIRST, "ÕˆÏÈÔOÖÃϵ½y…¢”µ."},
{IDS_STATUS_SMTPFROM, "°lËÍ SMTP from µØÖ·"},
{IDS_STATUS_SMTPTO, "°lËÍ SMTP to µØÖ·"},
{IDS_STATUS_TRANSFERING, "‚÷Ý”ÕýÎÄ”µ“þ..."},
{IDS_STATUS_GETPORT, "™zË÷ TCP/IP ¾W½j¶Ë¿Ú..."},
{IDS_STATUS_RETRIVEADDRESS, "™zË÷ internet µØÖ·..."},
{IDS_STATUS_GETPROTOCOL, "™zË÷¾W½j…f×h..."},
{IDS_STATUS_CREATESOCKET, "„“½¨ socket..."},
{IDS_STATUS_ESTABLISHCONNECT, "½¨Á¢¾W½jßB½Ó..."},
{IDS_STATUS_GETHOSTNAME, "™zË÷Ö÷™CÃû·Q..."},
{IDS_STATUS_CONNECTTOTCP, "Åc TCP ½¨Á¢ßB½Ó..."},
{IDS_STATUS_SENDHELO, "°lËÍ HELO ÐÅÏ¢..."},
{IDS_STATUS_REPLYHELO, "½ÓÊÕ HELO µÄ»Ø‘ª..."},
{IDS_STATUS_LASTTASK, "×îááµÄÈ΄Õ..."},
{IDS_STATUS_TRANFORMOK, "¾W½j‚÷Ý”³É¹¦."},
{IDS_STATUS_TRANSFORMERROR, "¾W½j‚÷ݔʧ”¡."},
{IDS_GAMP_READG3ERROR, "×x .g3 Îļþ•r³öåe£¬¿ÉÄÜËü²»ÊÇÕý´_µÄ¸ñʽ."},
{IDS_GAMP_FIRSTPAGE, "ËüÒѽ›ÊǵÚÒ»í“ÁË."},
{IDS_GAMP_LASTPAGE, "ËüÒѽ›ÊÇ×îááÒ»í“ÁË."},
{IDS_GAMP_PAGE, "í“Ì–"},
{IDS_GAMP_THREADLIST, "ß\ÐеĂ÷Ý”¾€³Ì"},
{IDS_GAMP_CURSTATUS, "®”Ç° î‘B"},
{IDS_GAMP_TERMINATE, "½KÖ¹"},
{IDS_GAMP_MEMORYERROR, "ƒÈ´æ³ö¬F‡ÀÖØåeÕ`!"},
{0,NULL}
};
///////////////////////////////////////////
////////language text item pointer/////////
LANG_POINTER langPointer[]={
{MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),&usaTextItem[0]},
{MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),&chsTextItem[0]},
{MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_TRADITIONAL),&twnTextItem[0]},
{0,NULL}
};
void SetCurrentLanguage(WORD langID)
{
int i=0;
while(1){
if(langPointer[i].langID==0){
gCurrentIndex=0;//English default even if error occurred
return;
}
if(langPointer[i].langID==langID)
break;
i++;
}
gCurrentIndex=i;
}
WORD GetCurrentLanguage()
{
return langPointer[gCurrentIndex].langID;
}
int LoadTextByID(UINT resID,LPTSTR string,int maxsize)
{
if(maxsize<=0)
return maxsize;
CString str;
LPTEXT_ITEM lpItem;
int copylength;
copylength=0;
if(gCurrentIndex==0){//English
str.LoadString(resID);
copylength=min(str.GetLength(),maxsize-1);
lstrcpy(string,str);
}
else{
lpItem=langPointer[gCurrentIndex].lpTextItem;
while(1){
if(lpItem->resID==0)
break;//it will never occur
if(lpItem->resID==resID){
copylength=min(lstrlen(lpItem->text),maxsize-1);
lstrcpy(string,lpItem->text);
break;
}
lpItem++;
}
}
return copylength;
};
#3
谢谢,有没有简单一点的方法?如果我还要换位图(对话框资源内),代码量应该比较大的。。。20分奉上。
#1
你可以为每一种语言建立一个资源动态库,在运行过程中根据不同的选择动态装入合适的动态库,并且所有的界面元素都从这个动态库中装入就行了——上面不应该有问题吧
#2
我刚完成一个国际化的网络应用程序,我是这样做的.
1:思路,UI的国际化分为两个部分,菜单和其它资源.
2:国际化的工作也就分为两个部分,菜单资源的ReLoad和其它UI(文本)的Reload.
3:菜单的ReLoad使用下面的函数(我的风格尽量不用MFC),菜单可以直接在资源文件.rc
中编辑.
BOOL ChangeMenu()
{
//////////////////////////////////////////////
//////It's difficult to change the menu///////
/////It's important to set m_hMenuDefault/////
/////to hNewMenu.First,I haven't do this,/////
/////error will occur whenever the window/////
/////be closed.The reason is,memory address///
////will change if HMENU changed.Yet,I can////
///////not find any information about ////////
///////m_hMenuDefault in Help document////////
HINSTANCE hInst;
HRSRC hRc;
HGLOBAL hGl;
WORD lang;
MENUTEMPLATE* lpTemp;
HMENU hOldMenu,hNewMenu;
lang=GetCurrentLanguage();
hInst=AfxGetResourceHandle();
hRc=::FindResourceEx(hInst,RT_MENU,
MAKEINTRESOURCE(IDR_MAINFRAME),lang);
if(hRc==NULL)
return FALSE;
hGl=::LoadResource(hInst,hRc);
if(hGl==NULL)
return FALSE;
lpTemp=(MENUTEMPLATE *)::LockResource(hGl);
if(lpTemp==NULL){
::FreeResource(hGl);
return FALSE;
}
hNewMenu=::LoadMenuIndirect(lpTemp);
if(hNewMenu==NULL){
::FreeResource(hGl);
::UnlockResource(hGl);
return FALSE;
}
hOldMenu=::GetMenu(m_hWnd);
if(hOldMenu)
::DestroyMenu(hOldMenu);
::SetMenu(m_hWnd,hNewMenu);
m_hMenuDefault=hNewMenu;
::FreeResource(hGl);
::UnlockResource(hGl);
return TRUE;
}
4:其它资源的Reload基于下面的思路:在资源文件.rc中全是英文资源,在textres.*文件中实现资源的Reload,看了下面的两个文件你应该会明白.
*****************textres.h****************************
#ifndef _TEXTRES_H
#define _TEXTRES_H
#include "resource.h"
typedef struct _text_item
{
UINT resID;
LPCTSTR text;
} TEXT_ITEM,FAR* LPTEXT_ITEM;
typedef struct _lang_pointer
{
WORD langID;
LPTEXT_ITEM lpTextItem;
} LANG_POINTER,FAR* LPLANG_POINTER;
void SetCurrentLanguage(WORD langID);
WORD GetCurrentLanguage();
int LoadTextByID(UINT resID,LPTSTR string,int maxsize);
//maxsize should include the terminating null character
#endif
*************************************************************
#include "StdAfx.h"
#include "textres.h"
int gCurrentIndex;
//////////////////////////////
/////English Text Resource////
////Retrieve from .rc file////
TEXT_ITEM usaTextItem[]={
{0,NULL}
};
///////////////////////////////////
////Chinese Simplified Resource////
///////Retrive until resID==0//////
TEXT_ITEM chsTextItem[]={
{IDS_GAMP_APPTITLE, "MailToFax 1.0"},
{IDS_FILTER, "´«ÕæÎļþ|*.g3|ËùÓÐÎļþ|*.*|"},
{IDS_GAMP_BROWSE, "ä¯ÀÀ"},
{IDS_GAMP_NAMEANDFAX, "Ãû³ÆºÍ´«ÕæºÅ:"},
{IDS_GAMP_SUBJECT, "Ö÷Ìâ"},
{IDS_GAMP_SEND, "·¢ËÍ"},
{IDS_GAMP_FILENAME, "ÎļþÃû³Æ:"},
{IDS_GAMP_COMMBOOK, "ͨѶ²¾"},
{IDS_GAMP_OK, "È·¶¨"},
{IDS_GAMP_CANCEL, "È¡Ïû"},
{IDS_GAMP_NEW, "ÐÂÔö"},
{IDS_GAMP_MODIFY, "ÐÞ¸Ä"},
{IDS_GAMP_DELETE, "ɾ³ý"},
{IDS_GAMP_NAME, "ÐÕÃû"},
{IDS_GAMP_FAXNO, "´«ÕæºÅ"},
{IDS_GAMP_COMPANY, "¹«Ë¾"},
{IDS_GAMP_CANNOTBEEMPTY, " ²»ÄÜΪ¿Õ."},
{IDS_GAMP_MUSTBENUMERIC, " ±ØÐëÊÇÊý×Ö."},
{IDS_GAMP_CANNOTBEZERO, " ²»ÄÜΪÁã."},
{IDS_GAMP_NODATAREMAINED, "ÒѾ­Ã»ÓÐÊý¾ÝÁË."},
{IDS_GAMP_NOROWSELECTED, "ÇëÏÈÑ¡ÔñÒ»ÐÐÊý¾Ý."},
{IDS_GAMP_DATABASEERROR, "Êý¾Ý¿â·ÃÎʳö´í."},
{IDS_GAMP_DATAEXIST, "Êý¾ÝÒѾ­´æÔÚ."},
{IDS_GAMP_ORIGCOPY, "Ç빺ÂòÕý°æÈí¼þ."},
{IDS_GAMP_FINDBY, "Ìõ¼þ²éѯ"},
{IDS_GAMP_QUERY, "²éѯ"},
{IDS_GAMP_SELECTED, "ÒѾ­Ñ¡Ôñ"},
{IDS_GAMP_NEXT, "ÏÂÒ»Ïî"},
{IDS_GAMP_NAMEFAXNONOTMATCH, "±ØÐë°´´Ë¸ñʽÊäÈë:\nName-FaxNo."},
{IDS_GAMP_LENGTHTOOLONG, "Ì«³¤ÁË."},
{IDS_GAMP_NOFOUNDDATA, "ûÓз¢ÏÖÆ¥ÅäµÄÏîÄ¿."},
{IDS_GAMP_USERID, "Óû§IDºÅ"},
{IDS_GAMP_PASSWORD, "Óû§¿ÚÁî"},
{IDS_GAMP_EMAILADDRESS, "»ØÓ¦EmailµØÖ·"},
{IDS_GAMP_GATEWAY, "Íø¹ØEmailµØÖ·"},
{IDS_GAMP_SERVER, "SMTP ·þÎñÆ÷"},
{IDS_GAMP_PORT, "SMTP ¶Ë¿Ú"},
{IDS_GAMP_FAXNAME, "´«Õæ»úÆ÷Ãû"},
{IDS_GAMP_SYSCONFIG, "ϵͳÉèÖÃ"},
{IDS_GAMP_INVALIDVALUE, " ÎÞЧµÄÊý¾Ý."},
{IDS_GAMP_BETWEEN9999, " ±ØÐëÏÞÖÆÔÚ1-9999."},
{IDS_GAMP_OPENFILEERROR, "´ò¿ªÎļþʱ³ö´í."},
{IDS_GAMP_FAILTOOLBAR, "´´½¨¹¤¾ßÌõʱ³ö´í."},
{IDS_GAMP_SETSYSCONFIGFIRST, "ÇëÏÈÉèÖÃϵͳ²ÎÊý."},
{IDS_STATUS_SMTPFROM, "·¢ËÍ SMTP from µØÖ·"},
{IDS_STATUS_SMTPTO, "·¢ËÍ SMTP to µØÖ·"},
{IDS_STATUS_TRANSFERING, "´«ÊäÕýÎÄÊý¾Ý..."},
{IDS_STATUS_GETPORT, "¼ìË÷ TCP/IP ÍøÂç¶Ë¿Ú..."},
{IDS_STATUS_RETRIVEADDRESS, "¼ìË÷ internet µØÖ·..."},
{IDS_STATUS_GETPROTOCOL, "¼ìË÷ÍøÂçЭÒé..."},
{IDS_STATUS_CREATESOCKET, "´´½¨ socket..."},
{IDS_STATUS_ESTABLISHCONNECT, "½¨Á¢ÍøÂçÁ¬½Ó..."},
{IDS_STATUS_GETHOSTNAME, "¼ìË÷Ö÷»úÃû³Æ..."},
{IDS_STATUS_CONNECTTOTCP, "Óë TCP ½¨Á¢Á¬½Ó..."},
{IDS_STATUS_SENDHELO, "·¢ËÍ HELO ÐÅÏ¢..."},
{IDS_STATUS_REPLYHELO, "½ÓÊÕ HELO µÄ»ØÓ¦..."},
{IDS_STATUS_LASTTASK, "×îºóµÄÈÎÎñ..."},
{IDS_STATUS_TRANFORMOK, "ÍøÂç´«Êä³É¹¦."},
{IDS_STATUS_TRANSFORMERROR, "ÍøÂç´«Êäʧ°Ü."},
{IDS_GAMP_READG3ERROR, "¶Á .g3 Îļþʱ³ö´í£¬¿ÉÄÜËü²»ÊÇÕýÈ·µÄ¸ñʽ."},
{IDS_GAMP_FIRSTPAGE, "ËüÒѾ­ÊǵÚÒ»Ò³ÁË."},
{IDS_GAMP_LASTPAGE, "ËüÒѾ­ÊÇ×îºóÒ»Ò³ÁË."},
{IDS_GAMP_PAGE, "Ò³ºÅ"},
{IDS_GAMP_THREADLIST, "ÔËÐеĴ«ÊäÏß³Ì"},
{IDS_GAMP_CURSTATUS, "µ±Ç°×´Ì¬"},
{IDS_GAMP_TERMINATE, "ÖÕÖ¹"},
{IDS_GAMP_MEMORYERROR, "ÄÚ´æ³öÏÖÑÏÖØ´íÎó!"},
{0,NULL}
};
///////////////////////////////////
///Chinese Traditional Resource////
///////Retrive until resID==0//////
TEXT_ITEM twnTextItem[]={
{IDS_GAMP_APPTITLE, "MailToFax 1.0"},
{IDS_FILTER, "‚÷ÕæÎļþ|*.g3|ËùÓÐÎļþ|*.*|"},
{IDS_GAMP_BROWSE, "žgÓ["},
{IDS_GAMP_NAMEANDFAX, "Ãû·QºÍ‚÷ÕæÌ–:"},
{IDS_GAMP_SUBJECT, "Ö÷î}"},
{IDS_GAMP_SEND, "°lËÍ"},
{IDS_GAMP_FILENAME, "ÎļþÃû·Q:"},
{IDS_GAMP_COMMBOOK, "ͨӍ²¾"},
{IDS_GAMP_OK, "´_¶¨"},
{IDS_GAMP_CANCEL, "È¡Ïû"},
{IDS_GAMP_NEW, "ÐÂÔö"},
{IDS_GAMP_MODIFY, "ÐÞ¸Ä"},
{IDS_GAMP_DELETE, "„h³ý"},
{IDS_GAMP_NAME, "ÐÕÃû"},
{IDS_GAMP_FAXNO, "‚÷ÕæÌ–"},
{IDS_GAMP_COMPANY, "¹«Ë¾"},
{IDS_GAMP_CANNOTBEEMPTY, " ²»ÄÜ ‘¿Õ."},
{IDS_GAMP_MUSTBENUMERIC, " ±ØíšÊÇ”µ×Ö."},
{IDS_GAMP_CANNOTBEZERO, " ²»ÄÜ ‘Áã."},
{IDS_GAMP_NODATAREMAINED, "Òѽ››]ÓДµ“þÁË."},
{IDS_GAMP_NOROWSELECTED, "ÕˆÏÈßx“ñÒ»ÐДµ“þ."},
{IDS_GAMP_DATABASEERROR, "”µ“þŽìÔL†–³öåe."},
{IDS_GAMP_DATAEXIST, "”µ“þÒѽ›´æÔÚ."},
{IDS_GAMP_ORIGCOPY, "ՈُÙIÕý°æÜ›¼þ."},
{IDS_GAMP_FINDBY, "—l¼þ²éÔƒ"},
{IDS_GAMP_QUERY, "²éÔƒ"},
{IDS_GAMP_SELECTED, "Òѽ›ßx“ñ"},
{IDS_GAMP_NEXT, "ÏÂÒ»í—"},
{IDS_GAMP_NAMEFAXNONOTMATCH, "±Øíš°´´Ë¸ñʽݔÈë:\nName-FaxNo."},
{IDS_GAMP_LENGTHTOOLONG, "Ì«éLÁË."},
{IDS_GAMP_NOFOUNDDATA, "›]Óаl¬FÆ¥ÅäµÄí—Ä¿."},
{IDS_GAMP_USERID, "ÓÑôIDÌ–"},
{IDS_GAMP_PASSWORD, "ÓÑô¿ÚÁî"},
{IDS_GAMP_EMAILADDRESS, "»Ø‘ªEmailµØÖ·"},
{IDS_GAMP_GATEWAY, "¾WêPEmailµØÖ·"},
{IDS_GAMP_SERVER, "SMTP ·þ„ÕÆ÷"},
{IDS_GAMP_PORT, "SMTP ¶Ë¿Ú"},
{IDS_GAMP_FAXNAME, "‚÷Õæ™CÆ÷Ãû"},
{IDS_GAMP_SYSCONFIG, "ϵ½yÔOÖÃ"},
{IDS_GAMP_INVALIDVALUE, " ŸoЧµÄ”µ“þ."},
{IDS_GAMP_BETWEEN9999, " ±ØíšÏÞÖÆÔÚ1-9999."},
{IDS_GAMP_OPENFILEERROR, "´òé_Îļþ•r³öåe."},
{IDS_GAMP_FAILTOOLBAR, "„“½¨¹¤¾ß—l•r³öåe."},
{IDS_GAMP_SETSYSCONFIGFIRST, "ÕˆÏÈÔOÖÃϵ½y…¢”µ."},
{IDS_STATUS_SMTPFROM, "°lËÍ SMTP from µØÖ·"},
{IDS_STATUS_SMTPTO, "°lËÍ SMTP to µØÖ·"},
{IDS_STATUS_TRANSFERING, "‚÷Ý”ÕýÎÄ”µ“þ..."},
{IDS_STATUS_GETPORT, "™zË÷ TCP/IP ¾W½j¶Ë¿Ú..."},
{IDS_STATUS_RETRIVEADDRESS, "™zË÷ internet µØÖ·..."},
{IDS_STATUS_GETPROTOCOL, "™zË÷¾W½j…f×h..."},
{IDS_STATUS_CREATESOCKET, "„“½¨ socket..."},
{IDS_STATUS_ESTABLISHCONNECT, "½¨Á¢¾W½jßB½Ó..."},
{IDS_STATUS_GETHOSTNAME, "™zË÷Ö÷™CÃû·Q..."},
{IDS_STATUS_CONNECTTOTCP, "Åc TCP ½¨Á¢ßB½Ó..."},
{IDS_STATUS_SENDHELO, "°lËÍ HELO ÐÅÏ¢..."},
{IDS_STATUS_REPLYHELO, "½ÓÊÕ HELO µÄ»Ø‘ª..."},
{IDS_STATUS_LASTTASK, "×îááµÄÈ΄Õ..."},
{IDS_STATUS_TRANFORMOK, "¾W½j‚÷Ý”³É¹¦."},
{IDS_STATUS_TRANSFORMERROR, "¾W½j‚÷ݔʧ”¡."},
{IDS_GAMP_READG3ERROR, "×x .g3 Îļþ•r³öåe£¬¿ÉÄÜËü²»ÊÇÕý´_µÄ¸ñʽ."},
{IDS_GAMP_FIRSTPAGE, "ËüÒѽ›ÊǵÚÒ»í“ÁË."},
{IDS_GAMP_LASTPAGE, "ËüÒѽ›ÊÇ×îááÒ»í“ÁË."},
{IDS_GAMP_PAGE, "í“Ì–"},
{IDS_GAMP_THREADLIST, "ß\ÐеĂ÷Ý”¾€³Ì"},
{IDS_GAMP_CURSTATUS, "®”Ç° î‘B"},
{IDS_GAMP_TERMINATE, "½KÖ¹"},
{IDS_GAMP_MEMORYERROR, "ƒÈ´æ³ö¬F‡ÀÖØåeÕ`!"},
{0,NULL}
};
///////////////////////////////////////////
////////language text item pointer/////////
LANG_POINTER langPointer[]={
{MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),&usaTextItem[0]},
{MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),&chsTextItem[0]},
{MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_TRADITIONAL),&twnTextItem[0]},
{0,NULL}
};
void SetCurrentLanguage(WORD langID)
{
int i=0;
while(1){
if(langPointer[i].langID==0){
gCurrentIndex=0;//English default even if error occurred
return;
}
if(langPointer[i].langID==langID)
break;
i++;
}
gCurrentIndex=i;
}
WORD GetCurrentLanguage()
{
return langPointer[gCurrentIndex].langID;
}
int LoadTextByID(UINT resID,LPTSTR string,int maxsize)
{
if(maxsize<=0)
return maxsize;
CString str;
LPTEXT_ITEM lpItem;
int copylength;
copylength=0;
if(gCurrentIndex==0){//English
str.LoadString(resID);
copylength=min(str.GetLength(),maxsize-1);
lstrcpy(string,str);
}
else{
lpItem=langPointer[gCurrentIndex].lpTextItem;
while(1){
if(lpItem->resID==0)
break;//it will never occur
if(lpItem->resID==resID){
copylength=min(lstrlen(lpItem->text),maxsize-1);
lstrcpy(string,lpItem->text);
break;
}
lpItem++;
}
}
return copylength;
};
1:思路,UI的国际化分为两个部分,菜单和其它资源.
2:国际化的工作也就分为两个部分,菜单资源的ReLoad和其它UI(文本)的Reload.
3:菜单的ReLoad使用下面的函数(我的风格尽量不用MFC),菜单可以直接在资源文件.rc
中编辑.
BOOL ChangeMenu()
{
//////////////////////////////////////////////
//////It's difficult to change the menu///////
/////It's important to set m_hMenuDefault/////
/////to hNewMenu.First,I haven't do this,/////
/////error will occur whenever the window/////
/////be closed.The reason is,memory address///
////will change if HMENU changed.Yet,I can////
///////not find any information about ////////
///////m_hMenuDefault in Help document////////
HINSTANCE hInst;
HRSRC hRc;
HGLOBAL hGl;
WORD lang;
MENUTEMPLATE* lpTemp;
HMENU hOldMenu,hNewMenu;
lang=GetCurrentLanguage();
hInst=AfxGetResourceHandle();
hRc=::FindResourceEx(hInst,RT_MENU,
MAKEINTRESOURCE(IDR_MAINFRAME),lang);
if(hRc==NULL)
return FALSE;
hGl=::LoadResource(hInst,hRc);
if(hGl==NULL)
return FALSE;
lpTemp=(MENUTEMPLATE *)::LockResource(hGl);
if(lpTemp==NULL){
::FreeResource(hGl);
return FALSE;
}
hNewMenu=::LoadMenuIndirect(lpTemp);
if(hNewMenu==NULL){
::FreeResource(hGl);
::UnlockResource(hGl);
return FALSE;
}
hOldMenu=::GetMenu(m_hWnd);
if(hOldMenu)
::DestroyMenu(hOldMenu);
::SetMenu(m_hWnd,hNewMenu);
m_hMenuDefault=hNewMenu;
::FreeResource(hGl);
::UnlockResource(hGl);
return TRUE;
}
4:其它资源的Reload基于下面的思路:在资源文件.rc中全是英文资源,在textres.*文件中实现资源的Reload,看了下面的两个文件你应该会明白.
*****************textres.h****************************
#ifndef _TEXTRES_H
#define _TEXTRES_H
#include "resource.h"
typedef struct _text_item
{
UINT resID;
LPCTSTR text;
} TEXT_ITEM,FAR* LPTEXT_ITEM;
typedef struct _lang_pointer
{
WORD langID;
LPTEXT_ITEM lpTextItem;
} LANG_POINTER,FAR* LPLANG_POINTER;
void SetCurrentLanguage(WORD langID);
WORD GetCurrentLanguage();
int LoadTextByID(UINT resID,LPTSTR string,int maxsize);
//maxsize should include the terminating null character
#endif
*************************************************************
#include "StdAfx.h"
#include "textres.h"
int gCurrentIndex;
//////////////////////////////
/////English Text Resource////
////Retrieve from .rc file////
TEXT_ITEM usaTextItem[]={
{0,NULL}
};
///////////////////////////////////
////Chinese Simplified Resource////
///////Retrive until resID==0//////
TEXT_ITEM chsTextItem[]={
{IDS_GAMP_APPTITLE, "MailToFax 1.0"},
{IDS_FILTER, "´«ÕæÎļþ|*.g3|ËùÓÐÎļþ|*.*|"},
{IDS_GAMP_BROWSE, "ä¯ÀÀ"},
{IDS_GAMP_NAMEANDFAX, "Ãû³ÆºÍ´«ÕæºÅ:"},
{IDS_GAMP_SUBJECT, "Ö÷Ìâ"},
{IDS_GAMP_SEND, "·¢ËÍ"},
{IDS_GAMP_FILENAME, "ÎļþÃû³Æ:"},
{IDS_GAMP_COMMBOOK, "ͨѶ²¾"},
{IDS_GAMP_OK, "È·¶¨"},
{IDS_GAMP_CANCEL, "È¡Ïû"},
{IDS_GAMP_NEW, "ÐÂÔö"},
{IDS_GAMP_MODIFY, "ÐÞ¸Ä"},
{IDS_GAMP_DELETE, "ɾ³ý"},
{IDS_GAMP_NAME, "ÐÕÃû"},
{IDS_GAMP_FAXNO, "´«ÕæºÅ"},
{IDS_GAMP_COMPANY, "¹«Ë¾"},
{IDS_GAMP_CANNOTBEEMPTY, " ²»ÄÜΪ¿Õ."},
{IDS_GAMP_MUSTBENUMERIC, " ±ØÐëÊÇÊý×Ö."},
{IDS_GAMP_CANNOTBEZERO, " ²»ÄÜΪÁã."},
{IDS_GAMP_NODATAREMAINED, "ÒѾ­Ã»ÓÐÊý¾ÝÁË."},
{IDS_GAMP_NOROWSELECTED, "ÇëÏÈÑ¡ÔñÒ»ÐÐÊý¾Ý."},
{IDS_GAMP_DATABASEERROR, "Êý¾Ý¿â·ÃÎʳö´í."},
{IDS_GAMP_DATAEXIST, "Êý¾ÝÒѾ­´æÔÚ."},
{IDS_GAMP_ORIGCOPY, "Ç빺ÂòÕý°æÈí¼þ."},
{IDS_GAMP_FINDBY, "Ìõ¼þ²éѯ"},
{IDS_GAMP_QUERY, "²éѯ"},
{IDS_GAMP_SELECTED, "ÒѾ­Ñ¡Ôñ"},
{IDS_GAMP_NEXT, "ÏÂÒ»Ïî"},
{IDS_GAMP_NAMEFAXNONOTMATCH, "±ØÐë°´´Ë¸ñʽÊäÈë:\nName-FaxNo."},
{IDS_GAMP_LENGTHTOOLONG, "Ì«³¤ÁË."},
{IDS_GAMP_NOFOUNDDATA, "ûÓз¢ÏÖÆ¥ÅäµÄÏîÄ¿."},
{IDS_GAMP_USERID, "Óû§IDºÅ"},
{IDS_GAMP_PASSWORD, "Óû§¿ÚÁî"},
{IDS_GAMP_EMAILADDRESS, "»ØÓ¦EmailµØÖ·"},
{IDS_GAMP_GATEWAY, "Íø¹ØEmailµØÖ·"},
{IDS_GAMP_SERVER, "SMTP ·þÎñÆ÷"},
{IDS_GAMP_PORT, "SMTP ¶Ë¿Ú"},
{IDS_GAMP_FAXNAME, "´«Õæ»úÆ÷Ãû"},
{IDS_GAMP_SYSCONFIG, "ϵͳÉèÖÃ"},
{IDS_GAMP_INVALIDVALUE, " ÎÞЧµÄÊý¾Ý."},
{IDS_GAMP_BETWEEN9999, " ±ØÐëÏÞÖÆÔÚ1-9999."},
{IDS_GAMP_OPENFILEERROR, "´ò¿ªÎļþʱ³ö´í."},
{IDS_GAMP_FAILTOOLBAR, "´´½¨¹¤¾ßÌõʱ³ö´í."},
{IDS_GAMP_SETSYSCONFIGFIRST, "ÇëÏÈÉèÖÃϵͳ²ÎÊý."},
{IDS_STATUS_SMTPFROM, "·¢ËÍ SMTP from µØÖ·"},
{IDS_STATUS_SMTPTO, "·¢ËÍ SMTP to µØÖ·"},
{IDS_STATUS_TRANSFERING, "´«ÊäÕýÎÄÊý¾Ý..."},
{IDS_STATUS_GETPORT, "¼ìË÷ TCP/IP ÍøÂç¶Ë¿Ú..."},
{IDS_STATUS_RETRIVEADDRESS, "¼ìË÷ internet µØÖ·..."},
{IDS_STATUS_GETPROTOCOL, "¼ìË÷ÍøÂçЭÒé..."},
{IDS_STATUS_CREATESOCKET, "´´½¨ socket..."},
{IDS_STATUS_ESTABLISHCONNECT, "½¨Á¢ÍøÂçÁ¬½Ó..."},
{IDS_STATUS_GETHOSTNAME, "¼ìË÷Ö÷»úÃû³Æ..."},
{IDS_STATUS_CONNECTTOTCP, "Óë TCP ½¨Á¢Á¬½Ó..."},
{IDS_STATUS_SENDHELO, "·¢ËÍ HELO ÐÅÏ¢..."},
{IDS_STATUS_REPLYHELO, "½ÓÊÕ HELO µÄ»ØÓ¦..."},
{IDS_STATUS_LASTTASK, "×îºóµÄÈÎÎñ..."},
{IDS_STATUS_TRANFORMOK, "ÍøÂç´«Êä³É¹¦."},
{IDS_STATUS_TRANSFORMERROR, "ÍøÂç´«Êäʧ°Ü."},
{IDS_GAMP_READG3ERROR, "¶Á .g3 Îļþʱ³ö´í£¬¿ÉÄÜËü²»ÊÇÕýÈ·µÄ¸ñʽ."},
{IDS_GAMP_FIRSTPAGE, "ËüÒѾ­ÊǵÚÒ»Ò³ÁË."},
{IDS_GAMP_LASTPAGE, "ËüÒѾ­ÊÇ×îºóÒ»Ò³ÁË."},
{IDS_GAMP_PAGE, "Ò³ºÅ"},
{IDS_GAMP_THREADLIST, "ÔËÐеĴ«ÊäÏß³Ì"},
{IDS_GAMP_CURSTATUS, "µ±Ç°×´Ì¬"},
{IDS_GAMP_TERMINATE, "ÖÕÖ¹"},
{IDS_GAMP_MEMORYERROR, "ÄÚ´æ³öÏÖÑÏÖØ´íÎó!"},
{0,NULL}
};
///////////////////////////////////
///Chinese Traditional Resource////
///////Retrive until resID==0//////
TEXT_ITEM twnTextItem[]={
{IDS_GAMP_APPTITLE, "MailToFax 1.0"},
{IDS_FILTER, "‚÷ÕæÎļþ|*.g3|ËùÓÐÎļþ|*.*|"},
{IDS_GAMP_BROWSE, "žgÓ["},
{IDS_GAMP_NAMEANDFAX, "Ãû·QºÍ‚÷ÕæÌ–:"},
{IDS_GAMP_SUBJECT, "Ö÷î}"},
{IDS_GAMP_SEND, "°lËÍ"},
{IDS_GAMP_FILENAME, "ÎļþÃû·Q:"},
{IDS_GAMP_COMMBOOK, "ͨӍ²¾"},
{IDS_GAMP_OK, "´_¶¨"},
{IDS_GAMP_CANCEL, "È¡Ïû"},
{IDS_GAMP_NEW, "ÐÂÔö"},
{IDS_GAMP_MODIFY, "ÐÞ¸Ä"},
{IDS_GAMP_DELETE, "„h³ý"},
{IDS_GAMP_NAME, "ÐÕÃû"},
{IDS_GAMP_FAXNO, "‚÷ÕæÌ–"},
{IDS_GAMP_COMPANY, "¹«Ë¾"},
{IDS_GAMP_CANNOTBEEMPTY, " ²»ÄÜ ‘¿Õ."},
{IDS_GAMP_MUSTBENUMERIC, " ±ØíšÊÇ”µ×Ö."},
{IDS_GAMP_CANNOTBEZERO, " ²»ÄÜ ‘Áã."},
{IDS_GAMP_NODATAREMAINED, "Òѽ››]ÓДµ“þÁË."},
{IDS_GAMP_NOROWSELECTED, "ÕˆÏÈßx“ñÒ»ÐДµ“þ."},
{IDS_GAMP_DATABASEERROR, "”µ“þŽìÔL†–³öåe."},
{IDS_GAMP_DATAEXIST, "”µ“þÒѽ›´æÔÚ."},
{IDS_GAMP_ORIGCOPY, "ՈُÙIÕý°æÜ›¼þ."},
{IDS_GAMP_FINDBY, "—l¼þ²éÔƒ"},
{IDS_GAMP_QUERY, "²éÔƒ"},
{IDS_GAMP_SELECTED, "Òѽ›ßx“ñ"},
{IDS_GAMP_NEXT, "ÏÂÒ»í—"},
{IDS_GAMP_NAMEFAXNONOTMATCH, "±Øíš°´´Ë¸ñʽݔÈë:\nName-FaxNo."},
{IDS_GAMP_LENGTHTOOLONG, "Ì«éLÁË."},
{IDS_GAMP_NOFOUNDDATA, "›]Óаl¬FÆ¥ÅäµÄí—Ä¿."},
{IDS_GAMP_USERID, "ÓÑôIDÌ–"},
{IDS_GAMP_PASSWORD, "ÓÑô¿ÚÁî"},
{IDS_GAMP_EMAILADDRESS, "»Ø‘ªEmailµØÖ·"},
{IDS_GAMP_GATEWAY, "¾WêPEmailµØÖ·"},
{IDS_GAMP_SERVER, "SMTP ·þ„ÕÆ÷"},
{IDS_GAMP_PORT, "SMTP ¶Ë¿Ú"},
{IDS_GAMP_FAXNAME, "‚÷Õæ™CÆ÷Ãû"},
{IDS_GAMP_SYSCONFIG, "ϵ½yÔOÖÃ"},
{IDS_GAMP_INVALIDVALUE, " ŸoЧµÄ”µ“þ."},
{IDS_GAMP_BETWEEN9999, " ±ØíšÏÞÖÆÔÚ1-9999."},
{IDS_GAMP_OPENFILEERROR, "´òé_Îļþ•r³öåe."},
{IDS_GAMP_FAILTOOLBAR, "„“½¨¹¤¾ß—l•r³öåe."},
{IDS_GAMP_SETSYSCONFIGFIRST, "ÕˆÏÈÔOÖÃϵ½y…¢”µ."},
{IDS_STATUS_SMTPFROM, "°lËÍ SMTP from µØÖ·"},
{IDS_STATUS_SMTPTO, "°lËÍ SMTP to µØÖ·"},
{IDS_STATUS_TRANSFERING, "‚÷Ý”ÕýÎÄ”µ“þ..."},
{IDS_STATUS_GETPORT, "™zË÷ TCP/IP ¾W½j¶Ë¿Ú..."},
{IDS_STATUS_RETRIVEADDRESS, "™zË÷ internet µØÖ·..."},
{IDS_STATUS_GETPROTOCOL, "™zË÷¾W½j…f×h..."},
{IDS_STATUS_CREATESOCKET, "„“½¨ socket..."},
{IDS_STATUS_ESTABLISHCONNECT, "½¨Á¢¾W½jßB½Ó..."},
{IDS_STATUS_GETHOSTNAME, "™zË÷Ö÷™CÃû·Q..."},
{IDS_STATUS_CONNECTTOTCP, "Åc TCP ½¨Á¢ßB½Ó..."},
{IDS_STATUS_SENDHELO, "°lËÍ HELO ÐÅÏ¢..."},
{IDS_STATUS_REPLYHELO, "½ÓÊÕ HELO µÄ»Ø‘ª..."},
{IDS_STATUS_LASTTASK, "×îááµÄÈ΄Õ..."},
{IDS_STATUS_TRANFORMOK, "¾W½j‚÷Ý”³É¹¦."},
{IDS_STATUS_TRANSFORMERROR, "¾W½j‚÷ݔʧ”¡."},
{IDS_GAMP_READG3ERROR, "×x .g3 Îļþ•r³öåe£¬¿ÉÄÜËü²»ÊÇÕý´_µÄ¸ñʽ."},
{IDS_GAMP_FIRSTPAGE, "ËüÒѽ›ÊǵÚÒ»í“ÁË."},
{IDS_GAMP_LASTPAGE, "ËüÒѽ›ÊÇ×îááÒ»í“ÁË."},
{IDS_GAMP_PAGE, "í“Ì–"},
{IDS_GAMP_THREADLIST, "ß\ÐеĂ÷Ý”¾€³Ì"},
{IDS_GAMP_CURSTATUS, "®”Ç° î‘B"},
{IDS_GAMP_TERMINATE, "½KÖ¹"},
{IDS_GAMP_MEMORYERROR, "ƒÈ´æ³ö¬F‡ÀÖØåeÕ`!"},
{0,NULL}
};
///////////////////////////////////////////
////////language text item pointer/////////
LANG_POINTER langPointer[]={
{MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),&usaTextItem[0]},
{MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),&chsTextItem[0]},
{MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_TRADITIONAL),&twnTextItem[0]},
{0,NULL}
};
void SetCurrentLanguage(WORD langID)
{
int i=0;
while(1){
if(langPointer[i].langID==0){
gCurrentIndex=0;//English default even if error occurred
return;
}
if(langPointer[i].langID==langID)
break;
i++;
}
gCurrentIndex=i;
}
WORD GetCurrentLanguage()
{
return langPointer[gCurrentIndex].langID;
}
int LoadTextByID(UINT resID,LPTSTR string,int maxsize)
{
if(maxsize<=0)
return maxsize;
CString str;
LPTEXT_ITEM lpItem;
int copylength;
copylength=0;
if(gCurrentIndex==0){//English
str.LoadString(resID);
copylength=min(str.GetLength(),maxsize-1);
lstrcpy(string,str);
}
else{
lpItem=langPointer[gCurrentIndex].lpTextItem;
while(1){
if(lpItem->resID==0)
break;//it will never occur
if(lpItem->resID==resID){
copylength=min(lstrlen(lpItem->text),maxsize-1);
lstrcpy(string,lpItem->text);
break;
}
lpItem++;
}
}
return copylength;
};
#3
谢谢,有没有简单一点的方法?如果我还要换位图(对话框资源内),代码量应该比较大的。。。20分奉上。