自绘CListCtrl防止闪烁的方法

自绘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();  
}

你可能感兴趣的:(自绘CListCtrl防止闪烁的方法)