MFC双缓存绘图实现

本文介绍了MFC中双缓存技术的实现,以解决视图窗口在进行复杂绘图操作时产生的闪烁问题。通过将绘图操作先在内存缓冲区完成,然后一次性复制到屏幕,显著减少了闪烁现象。

1. 前言

之前有一篇博客记录了如何在MFC的视图窗口上绘制图像,但是在后来的实际运行中出现了难以忍受的显示区域闪烁现象。产生这样问题的原因是频繁刷新视图窗口,且在当绘图操作复杂度越来越高的情况下越严重。在这样的情况下就要使用双缓存技术来缓解绘图区域闪烁的情况。所谓双缓存技术就是:使用内存缓冲区来解决由多重绘制操作造成的闪烁问题。当启用双缓冲时,所有绘制操作首先呈现到内存缓冲区,而不是屏幕上的绘图图面。所有绘制操作完成后,内存缓冲区直接复制到与其关联的绘图图面。

基于这样的操作不是直接操作绘图区域,而是操作内存中绘图,因而从人眼看到的画面角度闪烁会缓解很多。

2. 双缓存技术实现

在这里我就直接贴出双缓存实现的代码:
	//绘制背景色
	CClientDC dc(this);
	CRect *wndrect = new CRect;
	GetClientRect(wndrect);

	if (pDC == nullptr)
	{
		pDC = GetDC();
	}

	CDC dcMem;						//用于缓冲作图的内存DC
	CBitmap bmp;					//内存中承载临时图象的位图
	dcMem.CreateCompatibleDC(NULL);	//依附窗口DC创建兼容内存DC
	bmp.CreateCompatibleBitmap(pDC, wndrect->Width(), wndrect->Height());	//创建兼容位图,大小与绘图区一致
	dcMem.SelectObject(&bmp);		//将位图选择进内存DC,显示出来
	dcMem.FillSolidRect(wndrect, pDC->GetBkColor());//按原来背景填充客户区,不然会是黑色,这里原本在OnEraseBkgnd调用父类实现的,
													//此处实现也就有了原始的背景,然后在背景上作图,复制到DC内存

	CBrush cbrush;							//新笔刷
	CBrush* pBrush;							//旧笔刷
	cbrush.CreateSolidBrush(RGB(105, 105, 105));	//建立笔刷
	pBrush = dcMem.SelectObject(&cbrush);			//载入笔刷
	dcMem.FillRect(wndrect, &cbrush);				//填充底色
	dcMem.SelectObject(pBrush);						//恢复笔刷
	cbrush.DeleteObject();
	pBrush->DeleteObject();

	dcMem.SetTextColor(RGB(255, 255, 255));
	dcMem.SetBkMode(TRANSPARENT);
	dcMem.TextOut(0, 0, this->m_strID);

	//如果有图像数据就默认显示第一张图像数据
	if (this->m_Img.m_ImageContainer.size())
	{
		//CImage2DC::Show2DC(this->m_Img, dc.GetSafeHdc(), wndrect->Height(), wndrect->Width());
		this->m_Img.ShowImage(dcMem.GetSafeHdc(), *wndrect, this->m_Img.m_CurrentPos);
		//this->m_Img.DrawPatientInfo(TRUE);
		this->m_Img.DrawScalePlate(TRUE);
	}

	pDC->BitBlt(0, 0, wndrect->Width(), wndrect->Height(), &dcMem, 0, 0, SRCCOPY);//将内存DC上的图象拷贝到前台

	dcMem.DeleteDC();		//删除DC
	bmp.DeleteObject();		//删除位图
	ReleaseDC(pDC);
	delete wndrect;
	wndrect = nullptr;

运用双缓存技术之后,图像的闪烁有了明显改观:


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值