双缓存的问题。
最近在处理图形方面的东西在网上看到下面一段文字。
我们的绘图过程大多放在OnDraw或者OnPaint函数中,OnDraw在进行屏幕显示时是由OnPaint进行调用的。当窗口由于任何原因需要重绘时,总是先用背景色将显示区清除,然后才调用OnPaint,而背景色往往与绘图内容反差很大,这样在短时间内背景色与显示图形的交替出现,使得显示窗口看起来在闪。
..........................
这就要用到双缓存的方法了。双缓冲就是除了在屏幕上有图形进行显示以外,在内存中也有图形在绘制。我们可以把要显示的图形先在内存中绘制好,然后再一次性的将内存中的图形按照一个点一个点地覆盖到屏幕上去(这个过程非常快,因为是非常规整的内存拷贝)。这样在内存中绘图时,随便用什么反差大的背景色进行清除都不会闪,因为看不见。当贴到屏幕上时,因为内存中最终的图形与屏幕显示图形差别很小(如果没有运动,当然就没有差别),这样看起来就不会闪。
根据上面的解释,我试着做了一下,代码如下:
CBitmap m_bmTabBack;
m_bmTabBack.LoadBitmap(IDB_BITMAP1);
void CDoubleBufferDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect rect;
GetClientRect(&rect);
Draw(dc, rect);
CDC memDC;
memDC.CreateCompatibleDC(&dc);
CBitmap *pOld, bitmap;
bitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
pOld = memDC.SelectObject(&bitmap);
Draw(memDC, rect);
dc.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
memDC.SelectObject(pOld);
bitmap.DeleteObject();
memDC.DeleteDC();
}
void CDoubleBufferDlg::Draw(CDC& dc, RECT rect)
{
CDC memDC;
memDC.CreateCompatibleDC(&dc);
CBitmap *pOldBm = memDC.SelectObject(&m_bmTabBack);
dc.StretchBlt(rect.left, rect.top, rect.right - rect.left, 63, &memDC, 0, 7, 1, 63, SRCCOPY);
memDC.SelectObject(pOldBm);
memDC.DeleteDC();
}
大家看看这是双缓存了吧,我觉得是了。呵呵。(以前没有接触过,见笑了)
有两个问题不清楚。上面引用的文章中说“因为内存中最终的图形与屏幕显示图形差别很小(如果没有运动,当然就没有差别),这样看起来就不会闪。”可是如果仔细的看,也能看到背景色。
还有就是,在OnPaint函数中使用BitBlt函数拷贝内存块,有些不理解。上面几句代码已经在画面上绘画了,然后又把一个缓冲区中的东西覆盖上,是什么意思呢?我知道这是双缓存,但是给我的感觉是应该是在用后台缓存中的内容来替代背景色清除显示区的动作。
请朋友帮忙解释一个下。
我描述的有些不清楚,主要是自己还不怎么清楚,呵呵。希望朋友们讲得详细些。谢谢。