现在的位置: 首页 > 综合 > 正文

问题得以解决 qq截图框下的工具栏模拟

2013年11月21日 ⁄ 综合 ⁄ 共 2148字 ⁄ 字号 评论关闭

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

抱歉!评论已关闭.