自绘CListCtrl防止闪烁的方法

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

 

1.屏蔽WM_ERASEBKGND消息

<textarea cols="88" rows="4" name="code" class="cpp">BOOL CMyListCtrl::OnEraseBkgnd(CDC * pDC) { return FALSE; }</textarea>

 

2.在WM_PAINT消息中使用自已的双缓存

<textarea cols="90" rows="14" name="code" class="cpp">void CMyListCtrl::OnPaint() { CPaintDC dc(this); CRect rcClient,rcClip,rcHeader; GetClientRect(&amp;rcClient); GetHeaderCtrl()-&gt;GetWindowRect(&amp;rcHeader); dc.GetClipBox(&amp;rcClip); CDC MemDC; CBitmap MemBitmap, *pOldBitmap; MemDC.CreateCompatibleDC(&amp;dc); int nMode = MemDC.SetMapMode(dc.GetMapMode()); MemBitmap.CreateCompatibleBitmap(&amp;dc,rcClient.Width(),rcClient.Height()); pOldBitmap = MemDC.SelectObject(&amp;MemBitmap); MemDC.FillSolidRect(&amp;rcClient,GetBkColor()); CRgn rgn; rgn.CreateRectRgn(rcClip.left,rcClip.top,rcClip.right,rcClip.bottom); MemDC.SelectClipRgn(&amp;rgn); DefWindowProc(WM_PAINT,(WPARAM)MemDC.m_hDC,(LPARAM)0); MemDC.SelectClipRgn(NULL); if (rcClip.top &lt; rcHeader.Height()) rcClip.top = rcHeader.Height(); dc.BitBlt(rcClip.left,rcClip.top,rcClip.Width(),rcClip.Height(),&amp;MemDC,rcClip.left,rcClip.top,SRCCOPY); MemDC.SetMapMode(nMode); MemDC.SelectObject(pOldBitmap); MemDC.DeleteDC(); MemBitmap.DeleteObject(); rgn.DeleteObject(); }</textarea>

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