vc双缓冲:VC++双缓冲实现方法
在图形图象处理编程过程中,双缓冲是种基本技术我们知道,如果窗体在响应WM_PAINT消息时候要进行复
杂图形处理那么窗体在重绘时由于过频刷新而引起闪烁现象解决这问题有效思路方法就是双缓冲技术
窗体在刷新时总要有个擦除原来图象过程OnEraseBkgnd它利用背景色填充窗体绘图区然后在新绘图代码
进行重绘这样擦写造成了图象颜色反差当WM_PAINT响应很频繁时候这种反差也就越发明显于是我们就看到了
闪烁现象
我们会很自然想到避免背景色填充是最直接办法但是那样话窗体上会变团糟每次绘制图象时候都没有将原来图
象清除造成了图象残留于是窗体重绘时画面往往会变乱 7 8糟所以单纯禁止背景重绘是不够我们还要进行重新
绘图但要求速度很快于是我们想到了使用BitBlt它可以支持图形块复制速度很快我们可以先在内存中作图然后用
此将做好图复制到前台同时禁止背景刷新这样就消除了闪烁以上也就是双缓冲绘图基本思路
、普通思路方法:
先按普通做图思路方法进行编程即在视类OnDraw中添加绘图代码在此我们绘制若干同心圆代码如下:
CBCDoc* pDoc = GetDocument;
ASSERT_VALID(pDoc);
CPo ptCenter;
CRect rect,ellipseRect;
GetClientRect(&rect);
ptCenter = rect.CenterPo;
for( i=20;i>0;i--)
{
ellipseRect.SetRect(ptCenter,ptCenter);
ellipseRect.InflateRect(i*10,i*10);
pDC->Ellipse(ellipseRect);
}
编译运行尝试改变窗口大小可以发现闪烁现象
2、双缓冲思路方法:
在双缓冲思路方法中首先要做是屏蔽背景刷新背景刷新其实是在响应WM_ERASEBKGND消息我们在视类
中添加对这个消息响应可以看到缺省代码如下:
BOOL CMYView::OnEraseBkgnd(CDC* pDC)
{
CView::OnEraseBkgnd(pDC);
}
是父类OnEraseBkgnd我们屏蔽此只须直接 TRUE;即可
下面是内存缓冲作图步骤
CPo ptCenter;
CRect rect,ellipseRect;
GetClientRect(&rect);
ptCenter = rect.CenterPo;
CDC dcMem; //用于缓冲作图内存DC
CBitmap bmp; //内存中承载临时图象位图
dcMem.CreateCompatibleDC(pDC); //依附窗口DC创建兼容内存DC
bmp.CreateCompatibleBitmap(pDC,rect.Width,rect.Height);//创建兼容位图
dcMem.SelectObject(&bmp); //将位图选择进内存DC
//按原来背景填充客户区不然会是黑色
dcMem.FillSolidRect(rect,pDC->GetBkColor);
for( i=20;i>0;i--) //在内存DC上做同样同心圆图象
{
ellipseRect.SetRect(ptCenter,ptCenter);
ellipseRect.InflateRect(i*10,i*10);
dcMem.Ellipse(ellipseRect);
}
pDC->BitBlt(0,0,rect.Width,rect.Height,
&dcMem,0,0,SRCCOPY);//将内存DC上图象拷贝到前台
dcMem.DeleteDC; //删除DC
bm.DeleteObject; //删除位图
由于复杂画图操作转入后台我们看到是速度很快复制操作自然也就消除了闪烁现象
注意:bmp.CreateCompatibleBitmap(pDC,rect.Width,rect.Height);
这里面CreateCompatibleBitmap第个参数不能用dcMem这样话创建是黑白位图如果你要创建彩色位图需要用
pDC它用来创建了内存DC. 详细请见下面MSDN:
When a memory device context is created, it initially has a 1-by-1 monochrome bitmap selected o it.
If this memory device context is used in CreateCompatibleBitmap, the bitmap that is created is a
monochrome bitmap. To create a color bitmap, use the hDC that was used to create the memory
device context, as shown in the following code:
HDC memDC = CreateCompatibleDC ( hDC );
HBITMAP memBM = CreateCompatibleBitmap ( hDC, nWidth, nHeight );
SelectObject ( memDC, memBM );