使用MFC的双缓冲技术绘制图形时往往忽略一个细节---->对InvalidateRect函数的支持。


我们知道为了提高绘制效率,往往只对需要绘制的区域进行重绘,即调用InvalidateRect。


一般情况下的OnPaint处理代码是:

CWnd::OnPaint()

{

   CPaintDC    dc(this);

   CMemoryDC    memDC(&dc);


   // 使用memDC进行绘制

   DrawByMemoryDC(&memDC);

   // 拷贝至CPaintDC中

   dc.Bilt(memDC);

}


这里CPaintDC会对InvalidateRect函数传进来的Rect参数进行处理,未在Rect的区域不会进行像素绘制和拷贝操作,但是我们的CMemoryDC却没有这样的处理,因此双缓冲实现的效率很低。


为了解决这个问题,可以采用如下方法,将不需要绘制的区域裁剪出去:

CRect invalidateRect = dc.m_ps.rcPaint;    //dc为CPaintDC


if (invalidateRect.left > m_rtClient.left) //m_rtClient为客户区大小

{

CRect leftClipRect(m_rtClient.left, m_rtClient.top, invalidateRect.left, m_rtClient.bottom);

memDC.ExcludeClipRect(leftClipRect);

}


if (invalidateRect.top > m_rtClient.top)

{

CRect topClipRect(invalidateRect.left, m_rtClient.top, invalidateRect.right, invalidateRect.top);

memDC.ExcludeClipRect(topClipRect);

}


if (invalidateRect.bottom < m_rtClient.bottom)

{

CRect bottomClipRect(invalidateRect.left, invalidateRect.bottom, invalidateRect.right, m_rtClient.bottom);

memDC.ExcludeClipRect(bottomClipRect);

}


if (invalidateRect.right < m_rtClient.right)

{

CRect rightClipRect(invalidateRect.right, m_rtClient.top, m_rtClient.right, m_rtClient.bottom);

memDC.ExcludeClipRect(rightClipRect);

}