最近在学 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.