MFC如何高效地绘图

彻底解决MFC画面闪烁问题 闪烁的原因 画面闪烁的原因是一方面画面更新的太快,另一方面,采用了Invalidate(),即先擦除全部图画,再进行绘画,两者结合,导致画面闪烁,具体原理是绘画的图像和背景相差较大,即面积较大,颜色相差较大且每帧图像变化不明显,再加上频繁重绘,界面反复的在背景和图画间切换,最后的结果就就是闪烁严重。 探索解决办法 网上很多文章提出了双缓冲绘图法,这种办法虽然能够一定的缓解闪烁,但是还是没有从根本上解决上述问题,绘图过快的时候还是可能出现闪烁现象的,如果我们采用不擦除刷新,那么虽然每帧的图像差距不大了,不再闪 阅读详情
MFC如何高效地绘图  
   
  [   作者:   TouchMe       添加时间:   2001-12-25   8:21:34   ]  
   
     
   
        显示图形如何避免闪烁,如何提高显示效率是问得比较多的问题。  
  而且多数人认为MFC的绘图函数效率很低,总是想寻求其它的解决方案。  
  MFC的绘图效率的确不高但也不差,而且它的绘图函数使用非常简单,  
  只要使用方法得当,再加上一些技巧,用MFC可以得到效率很高的绘图程序。  
  我想就我长期(呵呵当然也只有2年多)使用MFC绘图的经验谈谈  
  我的一些观点。  
   
  1、显示的图形为什么会闪烁?  
        我们的绘图过程大多放在OnDraw或者OnPaint函数中,OnDraw在进行屏  
  幕显示时是由OnPaint进行调用的。当窗口由于任何原因需要重绘时,  
  总是先用背景色将显示区清除,然后才调用OnPaint,而背景色往往与绘图内容  
  反差很大,这样在短时间内背景色与显示图形的交替出现,使得显示窗口看起来  
  在闪。如果将背景刷设置成NULL,这样无论怎样重绘图形都不会闪了。  
  当然,这样做会使得窗口的显示乱成一团,因为重绘时没有背景色对原来  
  绘制的图形进行清除,而又叠加上了新的图形。  
        有的人会说,闪烁是因为绘图的速度太慢或者显示的图形太复杂造成的,  
  其实这样说并不对,绘图的显示速度对闪烁的影响不是根本性的。  
  例如在OnDraw(CDC   *pDC)中这样写:  
  pDC->MoveTo(0,0);  
  pDC->LineTo(100,100);  
  这个绘图过程应该是非常简单、非常快了吧,但是拉动窗口变化时还是会看见  
  闪烁。其实从道理上讲,画图的过程越复杂越慢闪烁应该越少,因为绘图用的  
  时间与用背景清除屏幕所花的时间的比例越大人对闪烁的感觉会越不明显。  
  比如:清楚屏幕时间为1s绘图时间也是为1s,这样在10s内的连续重画中就要闪  
  烁5次;如果清楚屏幕时间为1s不变,而绘图时间为9s,这样10s内的连续重画  
  只会闪烁一次。这个也可以试验,在OnDraw(CDC   *pDC)中这样写:  
  for(int   i=0;i<100000;i++)  
  {  
    pDC->MoveTo(0,i);  
    pDC->LineTo(1000,i);  
  }  
  呵呵,程序有点变态,但是能说明问题。  
        说到这里可能又有人要说了,为什么一个简单图形看起来没有复杂图形那么  
  闪呢?这是因为复杂图形占的面积大,重画时造成的反差比较大,所以感觉上要  
  闪得厉害一些,但是闪烁频率要低。  
        那为什么动画的重画频率高,而看起来却不闪?这里,我就要再次强调了,  
  闪烁是什么?闪烁就是反差,反差越大,闪烁越厉害。因为动画的连续两个帧之间  
  的差异很小所以看起来不闪。如果不信,可以在动画的每一帧中间加一张纯白的帧,  
  不闪才怪呢。  
   
   
  2、如何避免闪烁  
        在知道图形显示闪烁的原因之后,对症下药就好办了。首先当然是去掉MFC  
  提供的背景绘制过程了。实现的方法很多,  
    *   可以在窗口形成时给窗口的注册类的背景刷付NULL  
    *   也可以在形成以后修改背景  
  static   CBrush   brush(RGB(255,0,0));  
  SetClassLong(this->m_hWnd,GCL_HBRBACKGROUND,(LONG)(HBRUSH)brush);  
    *   要简单也可以重载OnEraseBkgnd(CDC*   pDC)直接返回TRUE  
        这样背景没有了,结果图形显示的确不闪了,但是显示也象前面所说的一样,  
  变得一团乱。怎么办?这就要用到双缓存的方法了。双缓冲就是除了在屏幕上有  
  图形进行显示以外,在内存中也有图形在绘制。我们可以把要显示的图形先在内存中  
  绘制好,然后再一次性的将内存中的图形按照一个点一个点地覆盖到屏幕上去(这个  
  过程非常快,因为是非常规整的内存拷贝)。这样在内存中绘图时,随便用什么反差  
  大的背景色进行清除都不会闪,因为看不见。当贴到屏幕上时,因为内存中最终的图形  
  与屏幕显示图形差别很小(如果没有运动,当然就没有差别),这样看起来就不会闪。  
   
   
  3、如何实现双缓冲  
        首先给出实现的程序,然后再解释,同样是在OnDraw(CDC   *pDC)中:  
   
  CDC   MemDC;   //首先定义一个显示设备对象  
  CBitmap   MemBitmap;//定义一个位图对象  
   
  //随后建立与屏幕显示兼容的内存显示设备  
  MemDC.CreateCompatibleDC(NULL);  
  //这时还不能绘图,因为没有地方画   ^_^  
  //下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小  
  MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight);  
     
  //将位图选入到内存显示设备中  
  //只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上  
  CBitmap   *pOldBit=MemDC.SelectObject(&MemBitmap);  
   
  //先用背景色将位图清除干净,这里我用的是白色作为背景  
  //你也可以用自己应该用的颜色  
  MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255));  
   
  //绘图  
  MemDC.MoveTo(……);  
  MemDC.LineTo(……);  
   
  //将内存中的图拷贝到屏幕上进行显示  
  pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY);  
   
  //绘图完成后的清理  
  MemBitmap.DeleteObject();  
  MemDC.DeleteDC();  
   
  上面的注释应该很详尽了,废话就不多说了。  
   
   
  4、如何提高绘图的效率  
        我主要做的是电力系统的网络图形的CAD软件,在一个窗口中往往要显示成千上万个电力元件,而每个元件又是由点、线、圆等基本图形构成。如果真要在一次重绘过程重画这么多元件,可想而知这个过程是非常漫长的。如果加上了图形的浏览功能,鼠标拖动图形滚动时需要进行大量的重绘,速度会慢得让用户将无法忍受。怎么办?只有再研究研究MFC的绘图过程了。  
        实际上,在OnDraw(CDC   *pDC)中绘制的图并不是所有都显示了的,例如:你  
  在OnDraw中画了两个矩形,在一次重绘中虽然两个矩形的绘制函数都有执行,但是很有可能只有一个显示了,这是因为MFC本身为了提高重绘的效率设置了裁剪区。裁剪区的作用就是:只有在这个区内的绘图过程才会真正有效,在区外的是无效的,即使在区外执行了绘图函数也是不会显示的。因为多数情况下窗口重绘的产生大多是因为窗口部分被遮挡或者窗口有滚动发生,改变的区域并不是整个图形而只有一小部分,这一部分需要改变的就是pDC中的裁剪区了。因为显示(往内存或者显存都叫显示)比绘图过程的计算要费时得多,有了裁剪区后显示的就只是应该显示的部分,大大提高了显示效率。但是这个裁剪区是MFC设置的,它已经为我们提高了显示效率,在进行复杂图形的绘制时如何进一步提高效率呢?那就只有去掉在裁剪区外的绘图过程了。可以先用pDC->GetClipBox()得到裁剪区,然后在绘图时判断你的图形是否在这个区内,如果在就画,不在就不画。  
  如果你的绘图过程不复杂,这样做可能对你的绘图效率不会有提高。
用MFC如何高效地绘图 用MFC如何高效地绘图TouchMe    显示图形如何避免闪烁,如何提高显示效率是问得比较多的问题。而且多数人认为MFC的绘图函数效率很低,总是想寻求其它的解决方案。MFC的绘图效率的确不高但也不差,而且它的绘图函数使用非常简单,只要使用方法得当,再加上一些技巧,用MFC可以得到效率很高的绘图程序。我想就我长期(呵呵当然也只有2年多)使用MFC绘图的经验谈谈我的一些观点。1、显示的图 阅读详情

相关推荐

Habitat-baselines v0.1.7防踩坑手把手带你跑通(全网唯一)

Habitat-baselines v0.1.7防踩坑手把手带你跑通(全网唯一)

shannanshouyin的博客 1277

OnPaint()闪烁问题

void CXinDlg::OnPaint()  {    if (IsIconic())    {       CPaintDC dc(this); // device context for painting       SendMessage(WM_ICONERASEBKGND, (WPARAM)dc.GetSafeHdc(), 0);       // Center icon in c

fuzaiyin5620的博客 1970

【强化学习】强化学习中,训练过程的稳定性是什么?该如何进行衡量?请详细进行解释

在强化学习中,训练过程的稳定性指的是算法在训练过程中表现出一致的行为,并且能够稳定地收敛到一个好的策略。收敛性:算法是否能够在有限的时间内收敛到一个近似最优的策略。鲁棒性:算法在不同的初始条件或环境扰动下的表现是否稳定。方差:算法在多次运行中表现出的变异程度。稳定的训练过程意味着算法的训练曲线平滑奖励信号变化小,且策略或价值函数的变化是渐进的。

wq6qeg88的博客 1630

解决Windows 程序界面闪烁问题的一些经验

本文转载自:http://blog.joycode.com/yaodong/archive/2004/11/26/39764.aspx 一般的windows 复杂的界面需要使用多层窗口而且要用贴图来美化,所以不可避免在窗口移动或者改变大小的时候出现闪烁。 先来谈谈闪烁产生的原因 原因一: 如果熟悉显卡原理的话,调用GDI函数向屏幕输出的时候并不是立刻就显示在屏幕 上只是写到了...

weixin_30838873的博客 225

WIFI 相关的频偏调试以及天线调试记录

WIFI RF 相关的频偏调试以及天线调试 1,频率误差(Frequency Error) 频率误差(Frequency Error):表征射频信号偏离该信号所处信道中心频率的大小,单位PPM。频偏误差要求范围如下表。 频偏越小越好。PPM的计算公式如下: 问题: 我们ESP8089认证测试的时候频偏测试超了。需要修改哪些呢。 测试频率点在2.411865385GHz 宣称点:2.412GHz 频率偏移计算:{(2.412GHz-2.411865385GHz)÷2...

armkits的博客 1万+

张量/数组存储方式与向量化展开/展平、view、reshape、permute对比

对于一个Tensor来说,我们可以认为它有两种存储方式。

欢迎关注,共同进步! 3434

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

一:为什么会产生界面闪烁? 解释这个之前,我们需要明白的是在MFC里面绘图的消息响应机制,大概的就是如果我们要在某一个 东西上面绘图,比如对话框,单文档等等,就必须先得到图形DC的句柄(handle),然后在指定句柄的基础上进行图形操作,也就是MFC常用的CDC *DC = this->getDC();其中的this就是你想画图的目标。 MFC里在消息响应的过程中,WM_PAINT被转变为OnDraw()(单文档 Single Document)或是OnPaint()(对 话框Dialog...

云海唯C的专栏 1053

保姆级教程:Windows下用GDC-Client下载TCGA数据,从环境变量配置到成功下载

本文提供Windows平台下使用GDC-Client下载TCGA数据的完整教程,从环境变量配置到成功下载。详细介绍了GDC-Client工具的安装、系统环境变量设置、配置文件优化以及数据下载实战技巧,帮助生物信息学研究者高效获取TCGA数据库中的癌症基因组数据。

weixin_42520025的博客 404

MFC 画直线 减少闪烁

最近一个作业,是MFC画直线。主要功能是三个:1.可以指定线的颜色:红色,绿色和蓝色。2.有四种画直线的方法。第一种用的是:SetROP2(R2_COPYPEN)                                 第二种用的是:SetROP2(R2_NOT)                                 第三种用的是:SetROP2(R2_XORPE

小辰蛋~ 2322

【ARM AMBA5 CHI 2 -- CHI 链路层详细介绍 】

目前有六个版本的 CHI 协议,CHI-A 是 CHI 协议的第一个版本。它提供了一个传输层,具有减少拥塞的功能。新通道、CHI 术语和组件命名的定义;请求、监听过滤器和缓存状态转换的示例;事务排序、独占访问和分布式虚拟内存(DVM)操作的规则;CHI-B 问题扩展了 CHI-A,但不能直接向后兼容 CHI-A。更大的物理地址宽度;原子事务;DVM 的 VMID 扩展;通道字段、事务结构和可靠性、可用性和可维护性(RAS)特性的描述;

CodingCos的博客 2536

openHarmony之AI Engine:万字讲解如何在应用、开发板上接入AI大模型调用

本文章介绍如何在 OpenHarmony 开发板上集成和部署各类 AI 大模型,实现终端直接聊天功能,并为语音助手、智能机器人等应用提供 AI 接口支持。

m0_67505153的博客 620

MFC如何高效的绘图

显示图形如何避免闪烁,如何提高显示效率是问得比较多的问题。 而且多数人认为MFC的绘图函数效率很低,总是想寻求其它的解决方案。 MFC的绘图效率的确不高但也不差,而且它的绘图函数使用非常简单, 只要使用方法得当,再加上一些技巧,用MFC可以得到效率很高的绘图程序。 我想就我长期(呵呵当然也只有2年多)使用MFC绘图的经验谈谈 我的一些观点。   1、显示的图形为什么会闪烁? 我们的绘图过程大多

脑袋不好使 2176

【应用】打造你的安全本地AI购物助手:OpenClaw + 淘宝MCP部署全攻略

本文介绍了在Ubuntu虚拟机中配置OpenClaw连接Windows宿主机的淘宝MCP服务的两种方案。核心原理是通过修改MCP服务监听地址或SSH隧道转发,实现跨网络访问。方案1推荐修改MCP服务绑定0.0.0.0并配置防火墙放行端口,适合长期使用;方案2通过SSH隧道转发,适合临时测试。文章详细说明了环境准备、配置文件修改及两种互通方案的具体实施步骤,重点解决了虚拟机与宿主机网络互通的关键问题。

海兰 1324

用MFC如何高效地绘图以及如何避免闪烁

  用MFC如何高效地绘图TouchMe    显示图形如何避免闪烁,如何提高显示效率是问得比较多的问题。而且多数人认为MFC的绘图函数效率很低,总是想寻求其它的解决方案。MFC的绘图效率的确不高但也不差,而且它的绘图函数使用非常简单,只要使用方法得当,再加上一些技巧,用MFC可以得到效率很高的绘图程序。我想就我长期(呵呵当然也只有2年多)使用MFC绘图的经验谈谈我的一些观点。1、

人在旅途/章鸽 的专栏 1646

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

[zz]用MFC如何高效地绘图

     TouchMe             显示图形如何避免闪烁,如何提高显示效率是问得比较多的问题。     而且多数人认为MFC的绘图函数效率很低,总是想寻求其它的解决方案。     MFC的绘图效率的确不高但也不差,而且它的绘图函数使用非常简单,     只要使用方法得当,再加上一些技巧,用MFC可以得到效率很高的绘图程序。     我想就我长期(呵呵当然也只有2年多)使用MFC绘图的

lijiecong的专栏 781

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

用 MFC 如何高效地绘图

         显示图形如何避免闪烁,如何提高显示效率是问得比较多的问题。而且多数人认为 MFC 的绘图函数效率很低,总是想寻求其它的解决方案。MFC 的绘图效率的确不高但也不差,而且它的绘图函数使用非常简单,只要使用方法得当,再加上一些技巧,用 MFC 可以得到效率很高的绘图程序。我想就我长期(呵呵当然也只有2年多)使用 MFC 绘图的经验谈谈我的一些观点。 1、显示的图形为什么会闪烁? ...

netstore的专栏 1352

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

[转贴]用MFC如何高效地绘图

<br /> 显示图形如何避免闪烁,如何提高显示效率是问得比较多的问题。 而且多数人认为MFC的绘图函数效率很低,总是想寻求其它的解决方案。 MFC的绘图效率的确不高但也不差,而且它的绘图函数使用非常简单, 只要使用方法得当,再加上一些技巧,用MFC可以得到效率很高的绘图程序。 我想就我长期(呵呵当然也只有2年多)使用MFC绘图的经验谈谈 我的一些观点。 1、显示的图形为什么会闪烁? 我们的绘图过程大多放在OnDraw或者OnPaint函数中,OnDraw在进行屏 幕显示时是由OnPaint进行调用的。当窗

Iamtheodore的专栏 563
上一篇: 防止对话框因ESC和ENTER键输入关闭的两种途径
下一篇: 使用manifest实现XP风格界面
qj840828
博客等级 码龄19年 11粉丝 35原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值