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:
上面是函数的实现,下面上个图显示其效果:
![](http://s7.sinaimg.cn/middle/636cc2e249fd5740e9cb6&690)
本来想从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自绘按钮的实现(NO MFC)
- 【转】 VC MFC 钩子 实现 自绘 窗体 标题栏 非客户区
- VC MFC 钩子 实现 自绘 窗体 标题栏 非客户区
- VC MFC 钩子 实现 自绘 窗体 标题栏 非客户区(VER.2013-11-06)
- VC自绘按钮的实现(NO MFC)
- VC/MFC 使用jsoncpp解析json格式内容
- VC7以上MFC实现的反射
- VC 实现自绘 窗体 标题栏 非客户区
- VC/MFC实现版本的在线升级提示和下载(服务器配置文件的方法)
- VC2010 MFC中实现printf调试功能,即MFC程序利用控制台输出调试信息
- VC MFC 全屏的快捷实现方法
- vc 一组单选按钮互斥的具体实现!!以及mfc内部如何实现具体的分组!!
- Matlab VC 联合编程 控制台以及MFC中实现(五)
- 用VC实现将自绘图形输出为bmp文件
- MFC + CxImage 实现自绘半透明按钮
- VC/MFC可编辑的列表控件的实现
- VC++ WIN32 sdk实现按钮自绘详解 之二(关键是BS_OWNERDRAW和WM_DRAWITEM)
- VC++基于CXImage库实现缩略图
- VC实现自绘图形输出到bmp文件
- VC++ WIN32 sdk实现按钮自绘详解.