MFC如何高效地绘图

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()得到裁剪区,然后在绘图时判断你的图形是否在这个区内,如果在就画,不在就不画。  
  如果你的绘图过程不复杂,这样做可能对你的绘图效率不会有提高。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Windows API 函数参考手册 本书编写组 编著 人民邮电出版社 内容简介 内容简介 本书是关于Microsoft Win32 API 函数的完整参考手册。 本书详细介绍了每一个Win32 API 函数的使用方法,其中着重介绍其原型表示、函数说 明、参数说明、注意事项、相应头文件(.H)、链接库(.LIB 或.DLL)和典型示例。对于每 个函数本书给出了相应的示例部分,这样读者在阅读相应的Win32 API 函数时就能很快地了 解它的具体功能和使用方法,便于更快地掌握该接口函数。 本书是从事Microsoft Windows 操作系统开发和应用人员的必备参考书,也可作为大专 院校相关专业师生自学、教学参考用书。 前 言 前 言 Microsoft Win32 API 是Microsoft Windows 操作系统提供的应用程序接口函数,它基本 上概括了应用程序编程中涉及的每个方面。我们在使用MFC 编程时,所用的MFC 函数都 是封装在Win32 API 基础之上的,即MFC 是Win32 API 的一个上层架构。学习Win32 API 能更深刻的理解MFC 的运作机制,同时使用Win32 API 函数编程要比使用MFC 更灵活, 能编写出更加高效的程序。Microsoft Win32 API 也可以在VB 和Delphi 等语言中使用。 Microsoft Win32 API 函数按照功能划分为窗口处理、设备上下文——DC 、绘图函数、 位图和图标、菜单处理、文件处理、同步、处理文本和字体、硬件和系统、Windows 消息、 进程和线程。 本书按功能对Win32 API 函数进行了划分,对于每一个功能部分的函数都具体给出了它 们的函数原型、功能和用法、注意事项、所在头文件、参数调用和典型示例等信息。本书内 容如下: 第 1 章介绍了Win32 应用程序的一些基本知识,例如系统消息传递机制,图形接口编 程等,同时,它也介绍了Win32 API 函数的一些基本知识。 第2 章介绍了关于窗口处理部分的Win32 API 函数,例如窗口创建,撤销等。 第3 章介绍了设备上下文——DC ,例如创建和获取DC 、坐标变换等。 第4 章介绍了绘图函数,例如路径、图元文件等。 第5 章介绍了位图和图标,例如从DLL 中获取图标,设置DIB 的颜色表等。 第6 章介绍了菜单的处理,例如上下文菜单显示,设置位图菜单项等。 第7 章介绍了文件的处理,例如文件查找,加锁和解锁文件等。 第8 章介绍了同步,例如互斥对象,信号量对象和关键段对象等。 第9 章介绍了文本和字体的处理,例如获取系统中字体的信息,输出各种形式的文本等。 第10 章介绍了硬件和系统,例如捕获鼠标,获取各种系统信息等。 第11 章介绍了Windows 消息,例如消息的获取和发送等。 第12 章介绍了进程和线程,例如调试进程和线程,获取和设置进程和线程的各种信息, 比如优先级、工作集等。 本书为立志掌握 Windows 操作系统编程的人提供了一条有效的捷径,对于不同层次的 Windows 操作系统编程人员来说,本书都极具参考价值,是一本不可多得的参考书。 参与本书的主要编写人员有张鸿超、张宏林等。
包含文件说明: 1. SolveFlashingAndRedrawv1.0.5 纯净版 无闪烁的MFC应用框架,实际使用时把此工程改名成你要建立的项目名称,然后开始开发即可。你熟悉MFC的话研究这个框架的半个小时应该就明白并熟练运用了。 2.SolveFlashingAndRedrawv1.0.5 demo版 利用SolveFlashingAndRedrawv1.0.4框架写的一个示例小程序,主要展示框架要实现的优点特性。 3.VCRn 修改vc工程名工具 ___作者 田彬.exe 用网上找到的一个MFC改工程名称的小工具,很实用。如果你想使用本框架就可以用它来改成你想要的工程名了。 4. 未使用本框架的类似功能简化程序 没有使用框架的程序,实现的功能和Demo类似。但是运行之后改变窗口大小等,会发现图形闪烁很厉害! 5. SolveFlashingAndRedrawv1.0.5 demo版 运行截图.jpg 6. ReadMe.txt 说明文件。 补充说明: 工程使用vc6.0开发,如果你用vc6.0双击.dsw文件无法打开,请先打开vc6.0然后把.dsw拖动到vc上面。 如果这种方法还是无法打开,你新建一个vc6.0 mfc sdi程序,把示例中框架拷贝到这个新工程中,运行即可,代码量不是太多。 框架说明: /****************************************************** SolveFlashingAndRedraw框架说明 ******************************************************/ /** 项目名称: demo框架 版本号: v1.0.5 第一作者: Jef 地址: 中国/江苏 日期: 20100724 电子邮箱: [email protected] 版权: 1.您可以修改及免费使用本程序。 2.修改之后附上您的个人信息发送到上面的作者邮箱,作者负责在全面测试后发布您修改后的新版本。 3.您使用本程序而导致任何伤害以及经济损失,由过错方依法承担所有责任,一概与第一作者及合作单位无关。 4.如果您使用本程序则表示您已经同意此版本协议!否则请勿使用! 项目功能: SolveFlashingAndRedraw框架是MFC解决窗口保存及重绘闪烁问题的一种比较好的方案(Win32解决方法类似)。 版本历史: v1.0.1 20091126 第一版本 v1.0.2 20091212 第二版本 1. 修改了部分变量的名字使其更符合其意义 2. 增加为两个工程,一是带demo例子的,另一是不带demo的纯净版. 3. 修改了其中一个错误. 如 CreateCompatibleDC之后没有调用DeleteDC等. v1.0.3 对v1.0.2进行了整理 v1.0.4 20100416 在v1.0.3的基础上进行整理,并增加了裁剪区,提高了绘图效率! v1.0.5 20100724 1. 添加了一个工具类CMemBmpDc,帮助产生一个内存DC,并把指定的内存位图选进去。方便绘图。 2. 演示了在适当时机如何高效画图,见Demo版的DrawSinwave(bool bDrawOnScreen)函数。 演示了用两种方法来绘图, 方法1. 直接绘图到屏幕上, 同时绘图到内存位图上,内存位图不会立即贴到屏幕上减少了内存拷贝的时间,提高了效率, 将来窗口失效时OnPait贴图到屏幕上. 这种方法的优点时减小了不必要的内存拷贝,缺点时当绘图内存复杂并且非常耗时可能会导致闪烁。 故适用于像本Demo的这样绘图(本例函数只绘制一小段直线)。 方法2. 绘制到内存位图上后把应该重绘的这一小块设成裁剪区,然后立即OnPait重绘这个裁剪区。 运行步骤: 直接运行demo里面的程序,在窗口上任意拖拉鼠标画线,然后点击菜单栏的几个示范菜单项,然后移动窗口、 改变窗口大小、最大最小化窗口、用其它窗口覆盖此窗口、鼠标放到任务栏。。。 以上种种操作观察窗口内的图像变化。可以发现窗口内图像几乎看不到闪烁,而且窗口的元素已经保存下来重绘时任然可以看到图像。 如何使用: 进行项目开发时,可以先建立项目,然后把本解决方案框架拷贝到新建项目中即可。 也可以自己根据需要修改纯净版。 其它: 友情提示,小心 View类头文件及View类的实现文件中有说明,使用时别把它弄到你实际项目里哦! 进行大量复杂的图形的输出,而且对效率要求特别高时要考虑适当修改此框架(如增加裁剪区)后再使用哦。 关于如何在此框架的基础上提高绘图效率可以参阅下面的文章 如何提高绘图的效率 文章摘录 http://hi.baidu.com/new8sun/blog/item/68ccba8a80c3aadafc1f1079.html MFC双缓冲解决图象闪烁 2009-06-13 23:03 显示图形如何避免闪烁,如何提高显示效率是问得比较多的问题。而且多数人认为MFC绘图函数效率很低,总是想寻求其它的解决方案。 MFC绘图效率的确不高但也不差,而且它的绘图函数使用非常简单,只要使用方法得当,再加上一些技巧,用MFC可以得到效率很高的绘图程序。
### 回答1: MFC绘图控件是Microsoft Foundation Class库中的一个工具,它可以用来进行高速图表绘制。该控件具有快速绘图的能力,可以实时更新,并且支持鼠标响应。 MFC绘图控件可以通过MFC绘图示例(MFC Drawing Demo)来演示。该示例程序提供了一个基础的绘图框架,通过这个框架可以创建和绘制各种图形,如直线、矩形、圆等。使用示例程序可以学习和了解MFC绘图控件的基本用法和功能。 在示例程序中,鼠标响应是一个重要的功能。通过对鼠标事件的处理,可以实现一些交互式的操作,比如绘制自由曲线、移动和编辑已有图形等。例如,可以通过鼠标左键点击来创建一个点,通过拖动鼠标可以绘制直线或矩形等。 MFC绘图控件的高速性是其突出的特点之一。在图表绘制中,通常需要频繁地进行绘制操作,如果绘制速度太慢,会导致界面卡顿,影响用户体验。而MFC绘图控件通过利用底层硬件加速和绘图缓冲等技术,可以快速地进行图表绘制,保证了绘制效率和流畅度。 总而言之,MFC绘图控件是一个功能强大的工具,可以用于高速图表绘制。通过鼠标响应,可以实现更多的交互式操作。示例程序提供了一个演示和学习的平台,用户可以深入了解和使用MFC绘图控件的各种功能。 ### 回答2: high-speed charting control(MFC绘图控件)是一种用于在MFC应用程序中绘制快速和高效图表的控件。该控件的作用是帮助开发者在应用程序中实现各种类型的图表,如折线图、柱状图、饼图等。通过使用这个控件,开发者可以轻松地创建具有交互性和响应式的图表。 MFC绘图demo是一个包含了鼠标响应功能的示例程序。该示例程序展示了如何使用high-speed charting control控件来创建图表,并在用户与图表交互时响应鼠标的操作。 在这个demo中,开发者可以看到如何通过添加数据点来绘制折线图。通过鼠标的点击和拖动,用户可以添加、删除和移动数据点,实时更新图表的显示。该demo还演示了如何通过鼠标的滚动来放大和缩小图表的显示范围。 除了基本的绘制功能,MFC绘图demo还提供了一些其他功能,如图表的标注、背景设置和图表的保存与导入等。这些功能使得开发者可以根据实际需要进行图表的定制和扩展。 总结起来,high-speed charting control(MFC绘图控件)以及包含鼠标响应的MFC绘图demo是一种帮助开发者快速绘制高效图表的控件和示例程序。开发者可以根据自己的需求,使用这个控件和示例程序来实现各种类型的交互式图表功能。 ### 回答3: 高速绘图控件是MFC(Microsoft Foundation Classes)框架中的一个重要的组件之一,它可以用于在应用程序中实现图表的绘制和展示。MFC绘图Demo是一个示例程序,展示了如何使用MFC绘图控件来实现图表绘制,并通过鼠标响应来交互操作。 MFC绘图控件使用了高效绘图算法,能够快速地绘制图表数据,并具有良好的性能。它支持多种类型的图表,如曲线图、柱状图、饼状图等,并提供了丰富的参数和选项,可以用于定制图表的外观和行为。 MFC绘图Demo通过鼠标响应实现了图表的交互操作。用户可以使用鼠标来选择图表中的数据点、拖动图表的视图、放大缩小图表等。通过鼠标操作,用户可以方便地查看和分析图表数据,实现更直观的数据展示和操作。 在MFC绘图Demo中,通过监听鼠标事件,获取鼠标的坐标信息,并根据鼠标的操作来改变图表的显示和行为。例如,当用户点击某个数据点时,可以在图表上显示该数据点的数值或详细信息;当用户拖动图表视图时,可以实现平移图表的功能;当用户使用滚轮滚动鼠标时,可以实现图表的放大缩小。 总之,MFC高速绘图控件和MFC绘图Demo是用于实现图表绘制和交互操作的工具和示例程序,它们可以帮助开发人员快速构建和定制图表功能,并提供高效的数据展示和操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值