当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 可以显示多行文字的工具条

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 可以显示多行文字的工具条


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 93 ::
收藏到网摘: n/a

可以显示多行文字的工具条


作者:ahr


下载源代码


界面显示效果如图一:


图一 例子程序运行画面

CToolBar不支持多行文字,本文将通过一个定制的MFC/C++类 CMTToolBar 实现在工具条中显示多行文字。其思路是先把文字变成位图,再替换原来的工具条位图,达到显示多行文字的效果。这个类中最主要的一个成员函数是ShowText(UINT nIDResource),其定义如下:

// 显示工具条文字BOOL CMTToolBar::ShowText(UINT nIDResource){	// determine location of the bitmap in resource fork	HINSTANCE hInst = AfxFindResourceHandle(MAKEINTRESOURCE(nIDResource), RT_TOOLBAR);	HRSRC hRsrc = ::FindResource(hInst, MAKEINTRESOURCE(nIDResource), RT_TOOLBAR);	if (hRsrc == NULL)	return FALSE;	HGLOBAL hGlobal = LoadResource(hInst, hRsrc);	if (hGlobal == NULL)	return FALSE;	CToolBarData* pData = (CToolBarData*)LockResource(hGlobal);	if (pData == NULL)	return FALSE;	ASSERT(pData->wVersion == 1);	// 得到单个按钮的图像大小	CSize sizeImage(pData->wWidth, pData->wHeight);	// release the resource	UnlockResource(hGlobal);	FreeResource(hGlobal);	// 得到 CToolBarCtrl	CToolBarCtrl& bar = GetToolBarCtrl();	// 得到 ToolBarCtrl的DC	CDC *pdcCtrl = bar.GetDC();	CDC dcDst;	// 目标DC , 用于生成新位图	dcDst.CreateCompatibleDC(pdcCtrl);	// 新建字体	LOGFONT logFont;	ZeroMemory(&logFont,sizeof(logFont));	logFont.lfWidth = 6;	logFont.lfHeight = 12;	logFont.lfCharSet = GB2312_CHARSET;	strcpy(logFont.lfFaceName, "宋体" );	CFont fntNew;	fntNew.CreateFontIndirect(&logFont);	CFont *pfntOld = dcDst.SelectObject(&fntNew);	// 新单个按钮的图片大小	CSize sizeNewImage(sizeImage.cx, 0);	// 创建字符串数组	const int nCount = bar.GetButtonCount();	CStringArray *pstrArray = new CStringArray[nCount];	int nLines = 0;	// 文字行数	int	nIndex = 0;	int nCharHeight = 0;	// 单个字符高度	TBBUTTON	tb;	int nBtnCount = 0;	// 按钮个数(除去分隔条)	for (int i = 0; i < nCount; ++ i)	{	ZeroMemory(&tb, sizeof(TBBUTTON));	bar.GetButton(i, &tb);	// 如果是分隔条	if ((tb.fsStyle & TBSTYLE_SEP) == TBSTYLE_SEP)	{	continue;	}	CString strT;	strT.LoadString(tb.idCommand);	int nPos = strT.Find(_T(''\n'')) + 1;	while(nPos > 0)	{	int nPos2 = strT.Find(_T(''\n''), nPos);	int nIndex;	if(nPos2>nPos)	{	nIndex = pstrArray[nBtnCount].Add( strT.Mid(nPos, nPos2-nPos) );	nPos = nPos2 + 1;	}	else if(strT.GetLength() > nPos)	{	nIndex = pstrArray[nBtnCount].Add( strT.Mid(nPos) );	nPos = -1;	}	nLines = max(nLines, nIndex+1);	CSize size = dcDst.GetTextExtent(pstrArray[nBtnCount][nIndex]);	nCharHeight = max(size.cy, nCharHeight);	sizeNewImage.cx = max(size.cx, sizeNewImage.cx);	}	nBtnCount ++;	}	// 换算成实际像素	sizeNewImage.cy = nLines*nCharHeight;	// 读取工具条位图资源	CBitmap	bmpToolBar;	BITMAP	bmBitmap;	if (!bmpToolBar.Attach(LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(nIDResource), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_CREATEDIBSECTION |LR_LOADMAP3DCOLORS )) || !bmpToolBar.GetBitmap(&bmBitmap))	return FALSE;	// 取得位图总宽高	int nWidth = bmBitmap.bmWidth;	int nHeight = bmBitmap.bmHeight;	// 新位图的总宽高	int nWidthNew = sizeNewImage.cx * nBtnCount;	sizeNewImage.cy += nHeight;	int nHeightNew = sizeNewImage.cy;	CDC dcSrc;	// 源DC	dcSrc.CreateCompatibleDC(pdcCtrl);	CBitmap *pbmpOldSrc = dcSrc.SelectObject(&bmpToolBar);	CBitmap bmpDst;	// 新位图	bmpDst.CreateCompatibleBitmap(&dcSrc, nWidthNew, nHeightNew);	CBitmap *pbmpOldDst = dcDst.SelectObject(&bmpDst);	// 先填充背景色	dcDst.FillSolidRect(CRect(0, 0, nWidthNew, nHeightNew), ::GetSysColor(COLOR_BTNFACE));	dcDst.SetBkMode(TRANSPARENT);	// 设置透明背景方式	int nStartX = (sizeNewImage.cx-sizeImage.cx)/2;	// 计算开始横坐标