在实现对多国语言支持的时候,使用了一种根据选择不同语言,读取不同文件的方式,设置界面中的语言的方法。
文件的格式如下:
[Setting]
Language=0
[String]
IDD_1=AAA
IDD_2=BBB
IDD_3=CCC
其中Setting是"section name"用来区分关键字,language则是关键字,0是它的值
通过不同的值,来区分不同的语言。
主要通过以下函数实现读值得功能:nLanguage = GetPrivateProfileInt(_T("Setting"),_T("Language"),-1,szFilePath);
其中szFilePath是文件保存的路径
和界面需要的nLanguage 比较,把保存该语言的文件路径保存好,以便下一步的操作:
if(nLanguage == nID)
{
gStrFileName = szFilePath;
bFound = true;
break;
}
然后就可以按照下一个"section name"来取实际的字符了:
CString gLoadString(LPCTSTR szID)
{
GetPrivateProfileString(SECTION_NAME,szID,_T("Not found"),
gBufferString,BUFF_SIZE,gStrFileName);
return CString(gBufferString);
}
其中的szID就是文件中自己定义的ID,如上面的IDD_1、IDD_2等,“=”好后面的值就是返回的gBufferString:简体、繁體、english......就随便写了
值得一提的是,设置语言后,取得的文件路径、用来读文件返回字符串的函数(gLoadString)最好是全局的,因为不方面把每个UI部分的类都创建一个多语言翻译的类
对于设置对话框和设置菜单上的字体,还有点小技巧:
保存语言的文件最好把要设置的字符串的ID按类区分,比如:
IDD_MENU_XXX —— 菜单ID
IDD_Dialog_XXX —— 对话框ID
这样做的好处是,在进行字体设置时,不用太麻烦,如:
HWND hSubWnd = GetWindow(hWnd,GW_CHILD);
while(::IsWindow(hSubWnd))
{
szKey.Format(_T("IDD_Dialog_%d"),uDlgID,GetDlgCtrlID(hSubWnd));
if(GetPrivateProfileString(SECTION_NAME,szKey,szDefault,
gBufferString,BUFF_SIZE,gStrFileName) != 0)
{
SetWindowText(hSubWnd,gBufferString);
}
hSubWnd = GetWindow(hSubWnd,GW_HWNDNEXT);
}
又如:
CString szKey;
HMENU hSubMenu = NULL;
HMENU hMenu = GetMenu(hWnd);
if(hMenu == NULL)
{
return false;
}
UINT nMenuID;
int nSubCount;
int nCount = GetMenuItemCount(hMenu);
for (int i=0;i<nCount;i++)
{
GetMenuString(hMenu,i,gBufferString,BUFF_SIZE,MF_BYPOSITION);
szKey.Format(_T("IDD_MAINMENU_%d"),i);
WritePrivateProfileString(SECTION_NAME,szKey,gBufferString,gStrFileName);
hSubMenu = GetSubMenu(hMenu,i);
if(hSubMenu != NULL)
{
nSubCount = GetMenuItemCount(hSubMenu);
for (int j=0;j<nSubCount;j++)
{
nMenuID = GetMenuItemID(hSubMenu,j);
if(nMenuID == 0)
continue;
GetMenuString(hSubMenu,j,gBufferString,BUFF_SIZE,MF_BYPOSITION);
szKey.Format(_T("IDD_MENU_%d"),nMenuID);
WritePrivateProfileString(SECTION_NAME,szKey,gBufferString,gStrFileName);
}
}
}
最后,在工程APP中,选择你所支持的语言,即设置好本文开头的nID,大功告成。