使用 CMemoryDC 實現雙緩沖時,若直接在整個內存 DC 繪圖再 BitBlt 到屏幕,會忽略 InvalidateRect 指定的更新區域,導致每次重繪整個客戶區,效率低下。
void CWnd::OnPaint() {
CPaintDC dc(this);
CMemoryDC memDC(&dc);
DrawByMemoryDC(&memDC); // 全量繪圖
dc.BitBlt(..., &memDC); // 全量拷貝
}
rcPaint 裁剪不需要繪製的區域CRect invalidateRect = dc.m_ps.rcPaint; // 獲取無效區域
// 左側裁剪
if (invalidateRect.left > m_rtClient.left) {
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);
}
僅在無效區域內執行繪圖與拷貝操作,顯著提升重繪性能,尤其在大窗口、高頻更新場景下效果明顯。
本文出自「愛上層樓」博客,轉載請保留出處:原文鏈接