新設想——VC開發多語言界面支持的新招

最近在做一個小程序,要求實現對多語言界面顯示支持功能,並且,界面顯示內容用戶能夠自己設置。

初步設計用INI文件來配置顯示內容,換一種語言的配置文件,就能夠更換整個系統的顯示語言。考慮到系統規模很小,周期又短,不想用太複雜的方案來解決這個問題,當參考了很多網上類似的設計和代碼,發現都不是很滿足。

主要問題在于:絕大多數基于INI文件配置這種簡單應有實現的代碼,都是針對組件ID固定加載,寫死了組件的ID號,比如:以下是引用片段:

strCaption = fileManager.GetString(section,"IDC_Stc_ListStudent","");

SetDlgItemText(IDC_Stc_ListStudent,strCaption);

strCaption = fileManager.GetString(section,"IDC_Stc_AllContent","");

SetDlgItemText(IDC_Stc_AllContent,strCaption);

這樣:界面組件越多,加載代碼越長;每新增一個顯示窗口,又必須複制、粘貼類似的代碼,根據組件ID常量值來修改相關的加載項,很是不爽!

初步設想是:設計統一、通用的窗口組件Caption設置方法,對給定的Frame或Dialog等Window容器組件內的所以組件進行遍曆,當增、減顯示組件不對語言包加載代碼産生影響,達到自適應界面組件語言包加載效果。

這樣就産生一個新問題:語言包配置文件中的Caption值如何跟相關的組件正確地一一對應?

好友文國慶建議:用XML文件來定義這種對應關系。這個想法觸動了我:反正就是一個[Key,Value]的數據,就用已經實現的INI配置文件也可以啊。于是所有問題解決!

具體設計是:語言包配置文件就直接設置成組件ID與組件顯示信息的Hash表,Key = Value的形式,比如:BTnOK組件的ControlID爲「1003」,中文顯示Caption爲「登錄」,語言包配置內容就是「1003=登錄」。

語言包的加載過程爲2步實現:

首先,從語言包配置文件中,讀取所有配置的ID、Caption條目到Vector或者Array中。

其次,在遍曆指定窗口中所有組件時,每發現一個組件,就用其ID在已經加載的語言包數組中查找,找到就用配置的值修改組件Caption屬性;找不到,就認爲是不需要動態配置,不做處理。

配置文件實例:

配置項解釋:Section:[Login Dialog]:界面窗口;等號左邊:窗口中需要設置其Caption屬性的組件ID;等號左邊:窗口中需要設置其Caption屬性的組件Caption值;

[Login Dialog]

1001 = 用戶帳號

1002 = 用戶密碼

1017 = 登 錄

1018 = 退 出

語言包配置信息加載代碼:

以下是引用片段:

BOOL CLanguageManager::loadFromFile()

...{

BOOL bRead=FALSE;

int i;

ItemContext temp;

CStringArray itemBuf,valueBuf;

bRead = fileManager.GetSectionValues("Main Window",itemBuf,valueBuf);

if(bRead)

...{

for(i=0;i

...{

temp.UCtrlID = atoi(itemBuf.GetAt(i));

temp.strContext = valueBuf.GetAt(i);

m_vtContexts.push_back(temp);

}

}

itemBuf.RemoveAll();

valueBuf.RemoveAll();

bRead = fileManager.GetSectionValues("Login Dialog",itemBuf,valueBuf);

if(bRead)

...{

for(i=0;i

...{

temp.uCtrlID = atoi(itemBuf.GetAt(i));

temp.strContext = valueBuf.GetAt(i);

m_vtContexts.push_back(temp);

}

}

return bRead;

}

讀取語言包配置信息:

以下是引用片段:

BOOL CIniFile::GetSectionValues(CString Section, CStringArray &strItemBuf, CStringArray &strValueBuf)

...{

BOOL bRead = FALSE;

ReadIniFile();//打開文件

if(bFileExist == FALSE FileContainer.GetSize() < 0)

return bRead;//文件打開出錯或文件爲空,返回默認值

int i = 0;

int iFileLines = FileContainer.GetSize();

CString strline,str;

while(i

...{

strline = FileContainer.GetAt(i++);

strline.TrimLeft();

if(strline.GetLength()<=0)

continue; //跳過空行

if(strline.Left(2)=="//")

continue; //跳過注釋行

if(strline.GetAt(0)=='[')//查找Section,第一個必須爲[

...{

str=strline.Left(strline.Find("]"));//去掉]右邊

str=str.Right(str.GetLength()-str.Find("[")-1);//去掉[左邊

str.TrimLeft();

str.TrimRight();

if(Section == str)//找到Section

...{

while(i

...{

strline = FileContainer.GetAt(i++);

strline.TrimLeft();

if(strline.GetLength()<=0)

continue; //跳過空行

if(strline.GetAt(0)=='[')

return bRead;//假如到達下一個[],即找不到,返回默認值

if(strline.Left(2)=="//")

continue; //跳過注釋行

str = strline.Left(strline.Find("="));//去掉=右邊

str.TrimLeft();

str.TrimRight();

//保存等號左邊項

strItemBuf.Add(str);

str=strline.Right(strline.GetLength()-strline.Find("=")-1);//去掉=左邊

str.TrimLeft();

str.TrimRight();

//保存等號右邊項

strValueBuf.Add(str);

bRead = TRUE;

}

//當前Section遍曆結束

}

//沒有找到Section

}

//當前行遍曆結束

}

return bRead;

}

修改指定組件Caption屬性代碼:

以下是引用片段:

BOOL CLanguageManager::setControlCaption(CWnd * pCtrl, UINT ctrlID)

...{

BOOL isOK=FALSE;

for(int i=0;i

...{

isOK = (m_vtContexts[i].uCtrlID==ctrlID);

if(isOK)

...{

pCtrl->SetWindowText(m_vtContexts[i].strContext);

break;

}

}

return isOK;

}

遍曆設置指定窗口所有組件Caption屬性代碼:

以下是引用片段:

void CLanguageManager::setCaptionForWindow(CWnd * pWnd)

...{

//枚舉對話框中所有組件

CWnd *pCtrl = pWnd->GetWindow(GW_CHILD);

while(pCtrl!=NULL)

...{

UINT ctrlID = pCtrl->GetDlgCtrlID();

setControlCaption(pCtrl,ctrlID);

pCtrl = pCtrl->GetNextWindow();

}

}

· 湖北宜昌三峽壩區水面驚現神秘動物

近日,湖北宜昌,一段視頻在當地熱傳:有網友在三峽壩區拍到神秘動物,體型碩大數米長...

· 什麽是語段?語段的類型以及和句群、段落的區別與聯系是什麽?

句群是最高級的語言單位。 段落(自然段)是章法單位...

· 十八部好看的賭石類小說

以下是十八部(排名不分先後)好看的賭石類小說的簡介,喜歡的朋友可以去搜索書名閱讀...

 
更改口令的界面的開發 (VC和數據庫應用)
// ChangePswDlg.cpp : implementation file//#include "stdafx.h"#include "Address.h"#include "ChangePswDlg.h"#include "PswdSet.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[]...查看完整版>>更改口令的界面的開發 (VC和數據庫應用)
 
用VC實現支持多語言的程序
用VC實現支持多語言的程序 作者:新奧特視頻公司 最近要做個程序要求有中文和英文兩個版本,因此要把應用程序的資源文件COPY一份英文的。 方法一:在資源中用InsertCopy COPY一...查看完整版>>用VC實現支持多語言的程序
 
Windows 8 版 Firefox 開發中:將支持 Metro 界面及各項系統特色功能
Windows 8 版 Firefox 開發中:將支持 Metro 界面及各項系統特色功能
文章分類: 互聯網絡 Windows 8 擁有提供一般桌面模式的「經典」界面與適合觸控的全新 Metro 界面,這也讓各個軟件商需要更加緊腳步,盡快支持這個新系統的各項特色功能,准備搶先帶給使用者更好的使用體驗 -- 而在 ...查看完整版>>Windows 8 版 Firefox 開發中:將支持 Metro 界面及各項系統特色功能
 
專爲VB制做的多語言軟件開發工具,可以輕松完成對可視界面的多語言化.
專爲VB制做的多語言軟件開發工具,可以輕松完成對可視界面的多語言化. 專爲VB制做的多語言軟件開發工具,可以輕松完成對可視界面的多語言化. 專爲VB制做的多語言軟件開發工具,可以輕松完成對可視界面的多語言化...查看完整版>>專爲VB制做的多語言軟件開發工具,可以輕松完成對可視界面的多語言化.
 
專爲VB制做的多語言軟件開發工具,可以輕松完成對可視界面的多語言化.
專爲VB制做的多語言軟件開發工具,可以輕松完成對可視界面的多語言化,您只需要制做語言包母板後翻譯複制該母板即可.. 界面介紹如下:啓動圖標:點這裏將啓動該程序.程序將向您的代碼中添加以下代碼,以便您訪問語言包:AP...查看完整版>>專爲VB制做的多語言軟件開發工具,可以輕松完成對可視界面的多語言化.