最近在學 GDI+ 爲了提高實踐就寫了個圖片處理+繪圖程序。在寫創建選區的時候就發現屏幕一直閃爍,以爲我是在MouseMove事件裏不斷重繪整個窗口。這時我想到了雙緩衝。
GDI+ 的雙緩衝很簡單,下面貼一下我的代碼:
void OnDraw(CDC* pDC)
{
...
CRect rc;
GetClientRect(rc);
Bitemap bmp(rc.GetWidth(), rc.GetHeight);
Graphics* pGraphics = Graphics::FromImage(&bmp);
pDoc->Draw(pGraphics); // 繪圖操作都在這裏邊
delete pGraphics; // 這句到底要不要?召喚大神
Graphics graphics(pDC->m_hDC);
graphics.DrawImage(&bmp, 0, 0);
graphics.ReleaseHDC(pDC->m_hDC); // 還有這句到底要不要%>_<%
}
但是,用了雙緩衝後還是會閃爍,什麼原因呢,難道我寫錯了?這麼簡單的幾句話。。。。無奈在網上又搜了一下GDI版本的雙緩衝(代碼就不帖了)結果還是會閃爍。⊙﹏⊙b汗。所以我就懷疑不是雙緩衝的問題了。
折騰了一晚上,終於發現問題出在 CView::Invalidate(bErase = TURE) 這個函數上,因爲我是在 MouseMove 事件上調用 這個函數使窗口重繪的。注意這個參數 MSDN 的說明
The client area is marked for painting when the next WM_PAINT message occurs. The region can also be validated before a WM_PAINT message occurs by the ValidateRect or
ValidateRgn member function.
The bErase parameter specifies whether the background within the update area is to be erased when the update region is processed. If bErase is TRUE, the background is erased
when the BeginPaint member function is called; if bErase is FALSE, the background remains unchanged. If bErase is TRUE for any part of the update region, the background in the
entire region, not just in the given part, is erased.
Windows sends a WM_PAINT message whenever the CWnd update region is not empty and there are no other messages in the application queue for that window.