您的位置:首页 > 其它

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

2011-04-26 19:39 501 查看
本人最近在完成基于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:

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



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: