MFC双缓冲绘图解决界面闪烁问题

一:为什么会产生界面闪烁?

  解释这个之前,我们需要明白的是在MFC里面绘图的消息响应机制,大概的就是如果我们要在某一个 东西上面绘图,比如对话框,单文档等等,就必须先得到图形DC的句柄(handle),然后在指定句柄的基础上进行图形操作,也就是MFC常用的CDC *DC = this->getDC();其中的this就是你想画图的目标。

  MFC里在消息响应的过程中,WM_PAINT被转变为OnDraw()(单文档 Single Document)或是OnPaint()(对 话框Dialog)之类的一系列函数来响应,这些函数一般都有个参数CDC *pDC传入进来,因此在这些函数里面,我们只需直接调用画图函数就能画出图形,这也是为什么我们在上C++课的时候,所有的画图函数都是写在 OnDarw()里面的原因,而且画个矩形直接写个pDC->Rectangle(...)就OK了。

  接下来正式解释为何会产生闪烁,OnDraw()和OnPaint()函数每次被调用时都是窗口被移动或者被改变大小,也可以通过代码来强制刷新,类似View类里面Invalidate(),而在VC中每次在调用OnDraw()时系统都是先用背景画刷将画布清除,再执行画图命令,这样在系统每执行一次OnDraw()就会有一个空白页,这样和你的最终结果图象之间有一个非常短暂的空白,因而看起来闪烁,而且画面刷新越快闪烁越严重。

  在c++课堂上门画一些简单的图形,没有设计到界面刷新,即使涉及到了,也就刷新一次画面,频率不高,所以在课堂上我们完全感受不到屏幕闪烁,但是我在做C++课设的时候,需要对画面实时刷新,所以必须对画面监控,所以刷新频率很高,出现了闪烁。

二:用双缓冲绘图解决闪烁

  双缓冲就是除了在屏幕上有图形进行显示以外,在内存中也有图形在绘制。我们可以把要显示的图形先在内存中绘制好,然后再一次性的将内存中的图形按照一个点一个点地覆盖到屏幕上去(这个过程非常快,因为是非常规整的内存拷贝)。这样在内存中绘图时,随便用什么反差大的背景色进行清除都不会闪,因为看不见。当贴到屏幕上时,因为内存中最终的图形与屏幕显示图形差别很小(如果没有运动,当然就没有差别),这样看起来就不会闪。

  通俗的解释OnDraw()函数就是:一个画板,我画了再擦掉,我再画,我再擦.....画...擦...(闪一下)...画...擦...(闪一下)...画...擦...(闪一下)...画...擦...(闪一下)

  而双缓冲就是:一个画板,我不在画板上面画,我先在纸上画(纸就是内存),画了,我粘贴,我再画,我再贴,画...贴...(我不闪)...画...贴...(我不闪)...画...贴...(我不闪)

  于是这样就解决了画图闪烁问题,因为这样在内存中绘图时,随便用什么反差大的背景色进行清除都不会闪,因为贴的时候给挡住了,看不见。

  双缓冲实现:

CRect rc; // 定义一个矩形区域变量
GetClientRect(rc);
int nWidth = rc.Width();
int nHeight = rc.Height();

CDC *pDC = GetDC(); // 定义设备上下文
CDC MemDC; // 定义一个内存显示设备对象
CBitmap MemBitmap; // 定义一个位图对象

//建立与屏幕显示兼容的内存显示设备
MemDC.CreateCompatibleDC(pDC);
//建立一个与屏幕显示兼容的位图,位图的大小可选用窗口客户区的大小
MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight);
//将位图选入到内存显示设备中,只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
CBitmap *pOldBit = MemDC.SelectObject(&MemBitmap);
//先用背景色将位图清除干净,否则是黑色。这里用的是白色作为背景
MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255));

//绘图操作等在这里实现
MemDC.MoveTo(……);
MemDC.LineTo(……);
MemDC.Ellipse(……);

//将内存中的图拷贝到屏幕上进行显示
pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY);

//绘图完成后的清理
MemDC.SelectObject(pOldbitmap);
MemBitmap.DeleteObject();

  代码解释的很清楚了,不多说,不懂的函数一个一个自行百度。

  双缓冲绘图相关博文:blog.chinaunix.net/uid-14827902-id-3066421.html

  

时间: 2024-10-08 10:29:35

MFC双缓冲绘图解决界面闪烁问题的相关文章

【MFC】MFC绘制动态曲线,用双缓冲绘图技术防闪烁

摘自:http://zhy1987819.blog.163.com/blog/static/841427882011614103454335/ MFC绘制动态曲线,用双缓冲绘图技术防闪烁 2011-07-14 10:34:54|  分类: 学习笔记 |  标签:双缓冲绘图技术  mfc  动态曲线   |举报 |字号 订阅 先上效果图 随着时间的推移,曲线向右平移,同时X轴的时间坐标跟着更新.一.如何绘制动态曲线. 所谓动画,都是一帧一帧的图像连续呈现在用户面前形成的.所以如果你掌握了如何绘制静

MFC双缓冲绘图

在双缓冲方法中,首先要做的是屏蔽背景刷新.背景刷新其实是在响应WM_ERASEBKGND消息.我们在视类中添加对这个消息的响应,可以看到缺省的代码如下: BOOL CMYView::OnEraseBkgnd(CDC* pDC) { return CView::OnEraseBkgnd(pDC); } 是调用父类的OnEraseBkgnd函数,我们屏蔽此调用,只须直接return TRUE;即可. CDC dcMem;                                        

MFC双缓冲绘图(2015.09.24)

问题引入: 最近在尝试编写贪吃蛇游戏时遇到这么一个问题:当系统以较快频率向窗口发送WM_PAINT消息时,调用OnPaint()函数在窗口中绘制图形就会发生闪烁现象. 问题分析: 当我们把绘图过程放在OnPaint()函数中时(放在OnDraw()函数中也是如此,因为OnDraw()会被OnPaint()调用),由于频繁收到系统的WM_PAINT消息,窗口需要执行重绘.而重绘过程首先是执行了窗口内容的擦除(用当前背景色的画刷对窗口重新绘制),然后再根据绘图语句在窗口客户区中对窗口内容进行重绘.由

MFC双缓冲绘图实例

本人之前一直了解双缓冲绘图的基本原理,但是在研究很久之后才大概知道具体的使用过程,本文将详细介绍本人在实际项目中使用双缓冲绘图的案例. 实现功能:主界面显示某张包含人脸的图片,通过dlib detector获取到人脸上的68个关键点,绘制在图片上显示,然后通过鼠标拖动图片上的关键点,调整位置,之后保存.双缓冲主要能够解决拖动关键点时屏幕闪烁的问题,本文主要侧重在双缓冲的实现,其他功能概不介绍. 具体实现: 1.定义全局变量: CDC dc_mem://内存绘制dc CDC *dc://绘图dc

强制设置双缓冲DoubleBuffered 解决tableLayoutPanel 闪烁

tableLayoutPanel.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) .SetValue(tableLayoutPanel, true, null);

VC双缓冲绘图技术介绍

VC双缓冲绘图技术介绍 双缓冲绘图,它是一种基本的图形图像绘图技术.首先,它在内存中创建一个与屏幕绘图区域一致的对象,然后将图形绘制到内存中的这个对象上,最后把这个对象上的图形数据一次性地拷贝并显示到屏幕上.这种技术能够大大地提高绘图的速度,减少卡顿和闪屏的问题. 我们为什么要使用双缓冲技术来进行绘图? 在应用程序开发中,当图像信息数据量很大时,绘图可能需要几秒钟甚至更长的时间,这时,应用程序可能会出现卡顿的现象.另外,如果窗体在响应WM_PAINT消息的同时也要进行复杂的图形处理,那么窗体在重

GDI双缓冲绘图

一.简介 在进行复杂图形绘制时,若直接在屏幕DC上进行绘制,则会出现明显的闪烁.闪烁产生的原因是当绘制的图形较为 复杂时,图形绘制过程中就被刷新到屏幕上,导致结果断断续续地显示出来.双缓冲绘图的原理是在另开辟一块内存用于绘制,当所有绘制工作完成后将内存数据一 次性拷贝到屏幕上. 双缓冲绘图步骤: 创建兼容DC(CreateCompatibleDC) 创建兼容位图(CreateCompatibleBitmap) 将兼容位图选入兼容DC(SelectObject) 在兼容DC中进行绘制工作 将兼容D

C#-gdi绘图,双缓冲绘图,Paint事件的触发---ShinePans

在使用gdi技术绘图时,有时会发现图形线条不够流畅,或者在改变窗体大小时会闪烁不断的现象.(Use DoubleBuffer to solve it!)                                                                                                                                                                              

Win32下双缓冲绘图技术

一:双缓冲原理 为了解决窗口刷新频率过快所带来的闪烁问题,利用双缓冲技术进行绘图.所谓双缓冲技术,就是将资源加载到内存,然后复制内存数据到设备DC(这个比较快),避免了直接在设备DC上绘图(这个比较慢).打个简单的比方:有个画家在街边办了一个即时画展,在同一块画布上根据观众的要求画不同的图像,每当有一位观众制定要看什么画时,画家先把之前画布上的东西全部擦干净,再重新绘画.显然有一些经典的画像是大家都想看的,按照以前的老办法,画家每次都要重新画这幅图像,但这种擦了画,画了擦的方式很费时.所以画家想