MFC双缓冲绘图
我们知道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
期待楼主的分享。收藏了,赞赞。