本文共 2166 字,大约阅读时间需要 7 分钟。
下午辛辛苦苦的把300+M的VC2008FeaturePack下下来之后,安装时却说我还没装VS2008,郁闷的事怎么老是喜欢堆在一起跑过来?要我从新去装VC2008SP1版或去弄几个G的VS20101,倒不如自毁武功,从此不涉江湖!唯一的选择只能是放弃花哨的CMFCToolBar,回头再来啃你这个土的掉渣的CToolBar,可我真不能再面对那几行能倒背如流的代码了,追本溯源,还是好好看看MSDN的好!闲话少说,得追求的效率了。
MSDN中对这个工具栏自绘消息:NM_CUSTOMDRAW的解释真是有点不厚道,明明照着他的意思去做却得不到想要的效果,于是将几个返回值按位或地赋给了*pResult,效果不错
当 *pResult=TBCDRF_NOBACKGROUND | TBCDRF_NOOFFSET; 系统的自绘边框居然消失了,这个真的是给我莫大的鼓舞,接下来可谓灵感大发,奇招百出啊!
首先是为工具栏设置背景问题,既然按钮完全覆盖了工具栏(至今我还没尝试过在工具栏上对按钮进行移动的方案,貌似很不便),那就在你按钮上着色好了,先准备好一具有同样背景色的位图,将其设为工具栏的NORMALA图片1,接着再将图片1的背景通过绘图软件弄成紫色(这个相当麻烦),要想紫色被透明掉,图片的背景色的RGB必须完全的等于(255,0,255),同时图片上的图标周围有蓝色边框,这个是作为工具栏HOT状态的图片2,接下来请看如下代码
void CTrueColorToolBar::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult){ LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR); // TODO: 在此添加控件通知处理程序代码 if(pNMCD->dwDrawStage==CDDS_PREPAINT) *pResult=CDRF_NOTIFYITEMDRAW; else if(pNMCD->dwDrawStage == CDDS_ITEMPREPAINT) {
CDC* pDC=CDC::FromHandle(pNMCD->hdc); CRect rc(pNMCD->rc); pDC->FillSolidRect(rc,RGB(220,239,251));
if (pNMCD->uItemState & CDIS_SELECTED) { int off=(rc.Width()-24)/-2-1; rc.InflateRect(off,off); pDC->FillSolidRect(rc,RGB(148,255,215)); } pDC->Detach();
*pResult=TBCDRF_NOBACKGROUND | TBCDRF_NOOFFSET;//不用系统的背景且按钮不移动 } //*pResult = 0;}
这样就能得到qq截图完毕时,那个工具栏80%的效果。
另外还少一个工具栏的外边框,如果至此不再改进,工具栏真是有点显的突兀。
VC6中可以通过WM_ERASEBKGND轻松绘制边框和背景,VC2008这却不行。第一想到的还是在工具栏上绘制,可效果不佳,因为每个按钮都有自己的dc,很难将它们各自的边框衔接起来,第二套方案是工具栏的老子,呵呵,也就是按钮的爷爷—对话框,因为工具栏是放在对话框上的,只有这样工具栏才能轻松地到处溜达(此处灵感要感谢临风大侠的提醒),为对话框绘制出同样的背景色,切有边框,且看
BOOL CToolBarDlg::OnEraseBkgnd(CDC* pDC){ // TODO: 在此添加消息处理程序代码和/或调用默认值 CRect rc; GetClientRect(rc); CBrush brush(RGB(220,239,251)); CPen pen(PS_SOLID,1,RGB(255,63,63)); CBrush* pOldBrush=pDC->SelectObject(&brush); CPen* pOldPen=pDC->SelectObject(&pen); pDC->Rectangle(rc); pDC->SelectObject(pOldBrush); pDC->SelectObject(pOldBrush); return true; return CDialog::OnEraseBkgnd(pDC);}此外还要将工具栏放到对话框的中间,对话框矩形仅比工具栏的长宽各大1个像素
如下:
CRect rc; m_wndToolBar.GetClientRect(&rc); rc.right=31*6;//使窗口与六个按钮一样宽,按钮宽为31 rc.OffsetRect(1,1); m_wndToolBar.MoveWindow(&rc); rc.right+=2; rc.bottom+=2; MoveWindow(&rc);
以上代码在对话框初始化中完成。还有个就是很重要的一点就是要使得m_wndToolBar具有CBRS_ALIGN_ANY 这个特性。
好了,qq截图工具栏模仿完毕!
转载地址:http://qrzti.baihongyu.com/