当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 可以显示多行文字的工具条
可以显示多行文字的工具条
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; // 计算开始横坐标 |