VS界面绘制双缓存

来源:互联网 发布:aws s3 上传文件 php 编辑:程序博客网 时间:2024/05/21 10:58
闪屏的问题

在GDI的绘图系统中,每调用一次区域绘图操作,如FillRect、BitBlt等,图形显示系统就会在屏幕中对指定的区域进行一次刷新操作。如果频繁的进行区域绘制操作的操作的话,我们就会发现,屏幕会出现闪屏。

双缓存
产生闪屏的原因是类似于多进程之间的通信问题,每次DC的绘图操作,都要把相关的显示数据发送到显卡,显卡处理后,在显示器上显示。借鉴提升多线程之间的通信效率的解决方法,可通过减少与显卡之间的交互次数来提升绘制的效率。这也就是双缓存的思路。双缓存的原理是先把更新操作中所有绘制数据先写入内存,然后再调用BitBlt或StretchBlt一次性的把所有数据发送到显卡中。

取消擦除背景
1.取消重绘时的擦除选项。如使用Invalidate(FALSE)。
2.截断擦除消息。背景的擦除是通过WM_ERASEBKGND消息来完成。于是,我们只要截获了该消息,就能彻底取消擦除背景。可在窗口类中为WM_ERASEBKGND提供消息响应函数,然后直接返回TRUE。

绘制效率的提升
在刷新界面的时候,刷新的区域越小,刷新效率更高,因此,在刷新界面的时候,我们应该尽量较少不必要的刷新。操作系统也会对界面的刷新操作进行优化,如拉动滚动条的时候,并不是对整个界面进行刷新,而只是对已经无效的区域中换上新的图形,然后再在屏幕调整图形区域在界面上的位置。因此,就有一个裁剪区域的概念,在重绘的过程中,只有裁剪区域需要重绘。因此,我们在双缓存中,也只需对裁剪区域重绘。可通过CDC::GetClipBox来获得裁剪区域的大小。


void CDlgTest::OnPaint(){CPaintDC dc(this); // device context for paintingCRect rcClient;GetClientRect(&rcClient);//创建内存DCCDC dcMem;dcMem.CreateCompatibleDC(&dc);//设置内存DC的画板CBitmap bmpMem;if (bmpMem.CreateCompatibleBitmap(&dc,rcClient.Width(),rcClient.Height())){CBitmap* pOldBmp = dcMem.SelectObject(&bmpMem);CWnd::DefWindowProc(WM_PAINT,(WPARAM)dcMem.m_hDC,0);/*功能实现代码。。。。。。*///把内存DC复制到输入DC中dc.BitBlt(0,0,rcClient.right,rcClient.bottom,&dcMem,0,0,SRCCOPY);//释放资源dcMem.SelectObject(pOldBmp);bmpMem.DeleteObject();}dcMem.DeleteDC();}


0 0
原创粉丝点击