日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

VC开发多语言界面支持的简单方法

發布時間:2025/3/21 c/c++ 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VC开发多语言界面支持的简单方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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<itemBuf.GetSize();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<itemBuf.GetSize();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<iFileLines)
??? ...{
??????? 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<iFileLines)
??????????????? ...{
??????????????????? 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<m_vtContexts.size();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();
??? }
}
發表于 @ 2007年08月29日 19:15:00 | 評論( 50 ) | 編輯| 舉報| 收藏


本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/CXXSoft/archive/2007/08/29/1764291.aspx

轉載于:https://www.cnblogs.com/kevinzhwl/archive/2010/05/07/3879006.html

總結

以上是生活随笔為你收集整理的VC开发多语言界面支持的简单方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。