下午辛辛苦苦的把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截图工具栏模仿完毕!