VC/MFC:CListView的自绘缩略图格式实现

来源:互联网 发布:java是前端还是后端 编辑:程序博客网 时间:2024/05/17 22:01

本人最近在完成基于CListview的缩略图显示时,实现了缩略图的显示与选中状态的修改,GetListCtrl()关联的CListctrl选中时有透明的蓝色,效果十分丑陋,本文介绍的方法可以实现选中后,用颜色画笔框起来的效果,并且可以更改缩略图的字体背景、字体样式等内容。

本来想从ClistCtrl关联ClistView入手解决自绘,但是发现好像ClistCtrl的派生类并不能关联到ClistView中,针对这种情况我想到可不可以直接在ClistView中添加自绘的响应过程呢,进一步,既然CMy**View是从CListView派生的那么直接在CMy**View中完成自绘是不是更直观呢?于是乎我们的自绘开始了:

step1:

声明消息响应函数:

(in CMy**View.h )

afx_msg void OnCustomDrawList ( NMHDR* pNMHDR, LRESULT* pResult );

加入消息映射:

(in CMy**View.cpp)

ON_NOTIFY_REFLECT ( NM_CUSTOMDRAW, OnCustomDrawList )

step2:

就是完成消息响应的定义了,此处画图我用的是GDI+,注释还是很详细的,就不多说了。

 

NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );

// Take the default processing unless we set this to something else below.
    *pResult = CDRF_DODEFAULT;
 
    // First thing - check the draw stage. If it's the control's prepaint
    // stage, then tell Windows we want messages for every item.
 
    if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
 {
        *pResult = CDRF_NOTIFYITEMDRAW;
 }
    else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
 {  
  LVITEM rItem;
        int nItem=static_cast<int>(pLVCD->nmcd.dwItemSpec);
  CDC *pDC=CDC::FromHandle(pLVCD->nmcd.hdc);
  COLORREF crBkgnd;
  BOOL bListHasFocus;

CRect rcItem;
  CRect rcText;
  CString sText;
  UINT uFormat;

bListHasFocus=(this->GetSafeHwnd()==::GetFocus());
  //get the image index and selected state of the item being draw
  ZeroMemory(&rItem,sizeof(LVITEM));
  rItem.mask=LVIF_IMAGE|LVIF_STATE;
  rItem.iItem=nItem;
  rItem.stateMask=LVIS_SELECTED|LVIS_FOCUSED;
  GetListCtrl().GetItem(&rItem);
  //draw the select background
  GetListCtrl().GetItemRect(nItem,&rcItem,LVIR_BOUNDS);
  int nBoundsWidth=rcItem.Width();
  
  if(rItem.state&LVIS_SELECTED)//when selected draw the Frameline
  {
   Graphics g(pDC->m_hDC);
   Pen pen(Color(255,255,0,0),2);
   g.DrawRectangle(&pen,rcItem.left,rcItem.top,rcItem.Width(),rcItem.Height());

}
  else
  {
            Graphics g(pDC->m_hDC);
   Pen pen(Color(255,221,224,231),2);
   g.DrawRectangle(&pen,rcItem.left,rcItem.top,rcItem.Width(),rcItem.Height()); 
  }
       //draw the icon ,delete the orginal blue background
       uFormat=ILD_TRANSPARENT;
    if((rItem.state&LVIS_SELECTED)&&bListHasFocus)
    {
         // uFormat|=ILD_FOCUS;
    }
      
    //get the rect that holds the item's icons
       CImageList *pImageList=GetListCtrl().GetImageList(LVSIL_NORMAL);
    if(pImageList)
    {
     IMAGEINFO ii;
     pImageList->GetImageInfo(rItem.iImage,&ii);
     pImageList->Draw(pDC,rItem.iImage,CPoint(rcItem.left+(nBoundsWidth-
              (ii.rcImage.right-ii.rcImage.left))/2,rcItem.top+2),uFormat);

}
      
    GetListCtrl().GetItemRect(nItem,&rcItem,LVIR_LABEL);//set the title of the iamge
       
    // Draw the background of the list item. Colors are selected
       // according to the item 's state.
   //设置字体颜色
        if (rItem.state & LVIS_SELECTED)
        {
            if (bListHasFocus)
            {
    crBkgnd = RGB(122,122,122);
    pDC->SetTextColor(crBkgnd);
            }
            else
            {
    crBkgnd = RGB(122,122,122);
    pDC->SetTextColor(crBkgnd);
            }
        }
        else
        {
   crBkgnd = RGB(122,122,122);
            pDC->SetTextColor(crBkgnd);
        }
 
        // Draw the background & prep the DC for the text drawing. Note
        // that the entire item RECT is filled in, so this emulates the full-
        // row selection style of normal lists.
        rcItem.OffsetRect(0, -2);

//       pDC->FillSolidRect(rcItem, crBkgnd);
        pDC->SetBkMode(TRANSPARENT);
 
        // Tweak the rect a bit for nicer-looking text alignment.
        rcText = rcItem;
        // Draw the text.
        sText = GetListCtrl().GetItemText(nItem, 0);
 
        pDC->DrawText(sText, CRect::CRect(rcText.left, rcText.top-3, rcText.right, rcText.bottom), DT_VCENTER | DT_CENTER);
 
        // Draw a focus rect around the item if necessary.
        if (bListHasFocus && (rItem.state & LVIS_FOCUSED))
        {
//            pDC->DrawFocusRect(rcItem);
        }

*pResult = CDRF_SKIPDEFAULT;

 

step3:

上面是函数的实现,下面上个图显示其效果:

VC/MFC:CListView的自绘缩略图格式实现