自绘CListCtrl防止闪烁的方法

简介:

自绘控件中经常会遇到闪烁的问题,主要原因是某个区域发生了重复性的绘制而导致的,而列表控件在自绘后闪烁原因是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();  
}
目录
相关文章
|
2月前
|
Windows
MASM32编程状态栏显示字符动画,按钮跑马灯
MASM32编程状态栏显示字符动画,按钮跑马灯
|
API iOS开发 Perl
iOS UIButton倒计时、指示器、粒子效果
iOS UIButton倒计时、指示器、粒子效果
iOS UIButton倒计时、指示器、粒子效果
|
Java
swing中一些常见的鼠标事件(鼠标形状的改变、鼠标接近、按下(图标的切换)、鼠标接近、离开(字体颜色的改变)、鼠标拖拽等)还有系统托盘+对话框
swing中一些常见的鼠标事件(鼠标形状的改变、鼠标接近、按下(图标的切换)、鼠标接近、离开(字体颜色的改变)、鼠标拖拽等)还有系统托盘+对话框
481 0
swing中一些常见的鼠标事件(鼠标形状的改变、鼠标接近、按下(图标的切换)、鼠标接近、离开(字体颜色的改变)、鼠标拖拽等)还有系统托盘+对话框
QT应用编程: 解决QGraphicsScene重写鼠标事件无法直接得到鼠标坐标问题
QT应用编程: 解决QGraphicsScene重写鼠标事件无法直接得到鼠标坐标问题
475 0
QT应用编程: 解决QGraphicsScene重写鼠标事件无法直接得到鼠标坐标问题