首页 > MFC > MFC双缓冲绘图

MFC双缓冲绘图

2012年10月9日 发表评论 阅读评论

我们知道MFC中如果高频率调用Invalidate方法的话,就会出现闪烁,因为每次都会刷新屏幕,擦除写入擦除写入,所以才会出现这个问题。我之前一直用了个很猥琐的方法,就是用OPENCV(链接里面的MFC中使用OPENCV显示图片API)。。这是多亏了opencv里面显示的机制本身估计。。。应该用的就是双缓冲吧。。最近老板交代写一个上位机也要画图,但是实际运行这个上位机的机子太破了,我可不想又搞什么opencv库在上面,而且将来放到别的机子上时还要附带上OPENCV的lib,DLL神马的,所以就将就用MFC自带的函数画图咯。。

所谓双缓冲就是我们是在内存中建立另外一个DC,然后画图都在这个内存DC中画,最后要现实的时候,直接用BitBlt直接进行图形块赋值,BitBlt好处在于非常之快!!而且我们要取消屏幕擦除,也就是Invalidate(FALSE),而不是TRUE。

比如说,我建立了一个基于对话框的项目,然后对话框内某个部件,PICTURE CONTROL,上面要动态地绘制一些图(曲线),那么我们在OnPaint()方法的最后添加下面这些代码:

CRect rect;
CDC *pDc; //屏幕绘图设备
CDC memDC; //内存绘图设备
//画得指定ID的控件的位置
GetDlgItem(IDC_STATIC1)->GetWindowRect(&rect);
GetDlgItem(IDC_STATIC1)->GetParent()->ScreenToClient(rect);
pDc = this->GetDC();// 指针

CBitmap memBitmap;
//创建内存绘图设备
memDC.CreateCompatibleDC(NULL);              
memBitmap.CreateCompatibleBitmap(pDc,rect.Width(),rect.Height());
memDC.SelectObject(&memBitmap);

//自己在memDC上随便画些图
memDC.FillSolidRect(CRect(0,0,rect.Width(),rect.Height()),RGB(255,0,0));//背景

memDC.MoveTo(CPoint(0,0));//画直线
memDC.LineTo(CPoint(rect.Width()*line_rate,rect.Height()*line_rate));
line_rate += 0.01;
if(line_rate >= 1)
    line_rate = 0;

////把内存绘图拷贝到屏幕
pDc->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY);
//释放内存
this->ReleaseDC(pDc);
memDC.DeleteDC();
memBitmap.DeleteObject();

当然,要先声明line_rate这个全局变量先。。

之后建立一个定时器,里面代码如下:

void CDoubleBufferDlg::OnTimer(UINT_PTR nIDEvent)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    CRect rect;
    GetDlgItem(IDC_STATIC1)->GetWindowRect(&rect);
    GetDlgItem(IDC_STATIC1)->GetParent()->ScreenToClient(rect);
    InvalidateRect(rect,FALSE);//局部更新,且不擦除!!
    CDialog::OnTimer(nIDEvent);
}

【完】

本文内容遵从CC版权协议,转载请注明出自http://www.kylen314.com

分类: MFC 标签: , ,