彻底解决MFC画面闪烁问题

闪烁的原因

画面闪烁的原因是一方面画面更新的太快,另一方面,采用了Invalidate(),即先擦除全部图画,再进行绘画,两者结合,导致画面闪烁,具体原理是绘画的图像和背景相差较大,即面积较大,颜色相差较大且每帧图像变化不明显,再加上频繁重绘,界面反复的在背景和图画间切换,最后的结果就就是闪烁严重。

探索解决办法

网上很多文章提出了双缓冲绘图法,这种办法虽然能够一定的缓解闪烁,但是还是没有从根本上解决上述问题,绘图过快的时候还是可能出现闪烁现象的,如果我们采用不擦除刷新,那么虽然每帧的图像差距不大了,不再闪烁了,但是却会把新的旧的图形混叠在一起。

问题解决办法

我们可以结合上述两种办法,首先,双缓冲绘图原理是设定一个和刷新区域大小相同的空位图,把整个函数中的绘图操作先在内存中执行,而不是直接在显示界面上去一步步执行,最后直接把内存中画好的图像贴到显示界面上,在内存中绘图之前还要采显示界面的背景色涂满位图,关键就在这一点上,每次绘图的时候内存中的图可以直接覆盖掉之前的图形,这时每次重绘前擦除全部图画就显得多此一举了,我们就可以用Invalidate(FALSE)进行界面刷新,而不用担心新旧图形混叠。

控件刷新闪烁问题

这个目前办法比较局限,还是在降低频率为主,如果不要求很高的实时性的话,就用定时器实时刷新就可以。

下面附上双缓冲绘图的核心代码,以对话框重绘为例:

void CXXDlg::OnPaint()
{
     
	CPaintDC pDC(this); // device context for painting
					   // TODO: 在此处添加消息处理程序代码
					   // 不为绘图消息调用 CDialogEx::OnPaint()

	CDC dc;//定义绘图句柄
	CBitmap MemBitmap;//定义位图单元
	dc.CreateCompatibleDC(NULL);//创建绘图句柄
	MemBitmap.CreateCompatibleBitmap(&pDC, thisDlgX + 20, thisDlgY + 50);//定义绘图大小 关联界面绘图句柄
	CBitmap *pOldBit = dc.SelectObject(&MemBitmap);//选取界面绘图句柄
	dc.FillSolidRect(0, 0, thisDlgX + 20, thisDlgY + 50, GetSysColor(COLOR_3DFACE));//用对话框背景色填充整个位图
	
	dc.MoveTo();//代表具体的绘图操作
	
	pDC.BitBlt(0, 0, thisDlgX + 20, thisDlgY + 50, &dc, 0, 0, SRCCOPY);//将画好的图片贴到界面上
	MemBitmap.DeleteObject();//删除位图单元
	dc.DeleteDC();//删除绘图句柄
}

你可能感兴趣的:(mfc,c++)