2024年2月19日发(作者:)
双缓冲的意思就是先将图画在内存中,然后再一次拷贝显示到屏幕上
画图一般是在OnPaint中画:
C/C++ code
CPoint ptCenter;
CRect rect,ellipseRect;
GetClientRect(&rect);
ptCenter = Point();
CDC dcMem; //用于缓冲作图的内存DC
CBitmap bmp; //内存中承载临时图象的位图
CompatibleDC(pDC); //依附窗口DC创建兼容内存DC (就是一个内存DC,所有图形先画在上面)
CompatibleBitmap(pDC,(),());//创建兼容位图
Object(&bmp); //将位图选择进内存DC
//按原来背景填充客户区,不然会是黑色
lidRect(rect,pDC->GetBkColor());
for(int i=20;i>0;i--) //在内存DC上做同样的同心圆图象
{
t(ptCenter,ptCenter);
eRect(i*10,i*10);
e(ellipseRect);
}
pDC->BitBlt(0,0,(),(),
&dcMem,0,0,SRCCOPY);//将内存DC上的图象拷贝到前台
MFC双缓冲绘图
2008-03-25 13:46
如何避免闪烁
在知道图形显示闪烁的原因之后,对症下药就好办了。首先当然是去掉MFC提供的背景绘制过程了。实现的方法很多,
* 可以在窗口形成时给窗口的注册类的背景刷付NULL
* 也可以在形成以后修改背景
static CBrush brush(RGB(255,0,0));
SetClassLong(this->m_hWnd,GCL_HBRBACKGROUND,(LONG)(HBRUSH)brush);
* 要简单也可以重载OnEraseBkgnd(CDC* pDC)直接返回TRUE
这样背景没有了,结果图形显示的确不闪了,但是显示也象前面所说的一样,变得一团乱。怎么办?这就要用到双缓存的方法了。双缓冲就是除了在屏幕上有图形进行显示以外,在内存中也有图形在绘制。我们可以把要显示的图形先在内存中绘制好,然后再一次性的将内存中的图形按照一个点一个点地覆盖到屏幕上去(这个过程非常快,因为是非常规整的内存拷贝)。这样在内存中绘图时,随便用什么反差大的背景色进行清除都不会闪,因为看不见。当贴到屏幕上时,因为内存中最终的图形与屏幕显示图形差别很小(如果没有运动,当然就没有差别),这样看起来就不会闪。
如何实现双缓冲
首先给出实现的程序,然后再解释,同样是在OnDraw(CDC *pDC)中:
CDC MemDC; //首先定义一个显示设备对象
CBitmap MemBitmap;//定义一个位图对象
//随后建立与屏幕显示兼容的内存显示设备
CompatibleDC(NULL);
//这时还不能绘图,因为没有地方画 ^_^
//下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
CompatibleBitmap(pDC,nWidth,nHeight);
//将位图选入到内存显示设备中
//只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
CBitmap *pOldBit=Object(&MemBitmap);
//先用背景色将位图清除干净,这里我用的是白色作为背景
//你也可以用自己应该用的颜色
lidRect(0,0,nWidth,nHeight,RGB(255,255,255));
//绘图
(……);
(……);
//将内存中的图拷贝到屏幕上进行显示
pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY);
//绘图完成后的清理
Object();
DC();
BOOL
CDataStructureView::OnEraseBkgnd(CDC* pDC)
{
CRect rc;
CDC dcMem;
GetClientRect(&rc);
CBitmap bmp; //内存中承载临时图象的位图
CompatibleDC(pDC); //依附窗口DC创建兼容内存DC
//创建兼容位图(必须用pDC创建,否则画出的图形变成黑色)
CompatibleBitmap(pDC,(),());
CBitmap *pOldBit=Object(&bmp);
//按原来背景填充客户区,不然会是黑色
lidRect(rc,RGB(255,255,255))
//画图,添加你要画图的代码,不过用dcMem画,而不是pDC;
......
pDC->BitBlt(0,0,(),(),&dcMem,0,0,SRCCOPY);
//将内存DC上的图象拷贝到前台
//绘图完成后的清理
DC(); //删除DC
Object(); //删除位图
return
true;
//这里一定要用return true,如果用自动生成的,会调用基类,把画出来的覆盖,就什 么结果也没有了
view sourceprint?
}


发布评论