牵着老婆满街逛

严以律己,宽以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

自绘CListCtrl防止闪烁的方法

转载自:http://blog.csdn.net/mynamelj/article/details/6571383

自绘控件中经常会遇到闪烁的问题,主要原因是某个区域发生了重复性的绘制而导致的,而列表控件在自绘后闪烁原因是WM_ERASEBKGND消息所导致的。解决定办法可以将这个消息屏蔽掉,然后使用双缓存,在Windows 5.1版本以后可以使用LVS_EX_DOUBLEBUFFER样式,为了各个版本的兼容性我个人不建议使用这个样式,因此我们可以拦截WM_PAINT消息来使用我们自已创建的双缓存,具体看代码所示:


 1.屏蔽WM_ERASEBKGND消息
BOOL CMyListCtrl::OnEraseBkgnd(CDC * pDC)  
{  
    
return FALSE;  
}

2.在WM_PAINT消息中使用自已的双缓存
void CMyListCtrl::OnPaint()  
{  
    CPaintDC dc(
this);  
  
    CRect rcClient,rcClip,rcHeader;  
    GetClientRect(
&rcClient);  
  
    GetHeaderCtrl()
->GetWindowRect(&rcHeader);  
    dc.GetClipBox(
&rcClip);  
  
    CDC MemDC;  
    CBitmap MemBitmap, 
*pOldBitmap;  
  
    MemDC.CreateCompatibleDC(
&dc);  
    
int nMode = MemDC.SetMapMode(dc.GetMapMode());  
  
    MemBitmap.CreateCompatibleBitmap(
&dc,rcClient.Width(),rcClient.Height());  
    pOldBitmap 
= MemDC.SelectObject(&MemBitmap);  
    MemDC.FillSolidRect(
&rcClient,GetBkColor());  
  
    CRgn rgn;  
    rgn.CreateRectRgn(rcClip.left,rcClip.top,rcClip.right,rcClip.bottom);  
    MemDC.SelectClipRgn(
&rgn);  
    DefWindowProc(WM_PAINT,(WPARAM)MemDC.m_hDC,(LPARAM)
0);  
    MemDC.SelectClipRgn(NULL);  
  
    
if (rcClip.top < rcHeader.Height())  
        rcClip.top 
= rcHeader.Height();  
  
    dc.BitBlt(rcClip.left,rcClip.top,rcClip.Width(),rcClip.Height(),
&MemDC,rcClip.left,rcClip.top,SRCCOPY);  
  
    MemDC.SetMapMode(nMode);  
    MemDC.SelectObject(pOldBitmap);  
    MemDC.DeleteDC();  
    MemBitmap.DeleteObject();  
    rgn.DeleteObject();  
}

posted on 2012-01-13 00:16 杨粼波 阅读(1333) 评论(0)  编辑 收藏 引用 所属分类: Windows


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理