当前位置: 首页 > news >正文

MFC中的窗口绘图问题

MFC中的窗口绘图问题

 

1.闪屏

如果按照常规的绘图过程,即每做完一个绘图操作,就马上进行窗口刷新,当绘图过程比较密集的时候,由于没绘制一次就刷新一次窗口,而刷新窗口是需要一定延时的,这就导致了在上一次的刷新还没有完成的时候,这一次的绘图又到来了,这就是常见的闪屏现象(screen flicker

 

2.双缓冲

         要避免闪屏的问题,只需要对每次绘图都进行窗口刷新,而是对所有的绘图完成之后再进行一次刷新,这既提高了效率,有避免了闪屏的问题。

         绘图的实质是将绘制的图形数据写入到一个内存块,然后计算机将这个内存块送到图像显示设备进行显示。默认的绘图过程也是如此,只不过它是每将一次的绘图数据写入到内存,就直接将这块内存发送到显示设备。而现在我们要做的是,将一个周期的内的绘图数据全部写入到同一个内存块中,这个周期完成之后,再将其送到显示设备。

代码的大致流程如下:

CBitmap memBmp;

CDC memDC;

memDC.CreateCompatibleDC(NULL);

   CDC *pDC=this->GetDC(); 

   CRect rect;

   m_chartBoard.GetWindowRect(rect);

   this->ScreenToClient(rect);

   memBmp.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());

   CBitmap *pOldBmp=memDC.SelectObject(&memBmp);

   COLORREF testColor=RGB(236,233,216);

   memDC.FillSolidRect(rect,testColor);

   //TODO:在这里使用memDC完成绘图操作

   pDC->BitBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY);

  

   memBmp.DeleteObject();

   memDC.DeleteDC();

同时要重写窗口类的afx_msg BOOL OnEraseBkgnd(CDC* pDC)函数

BOOL CPlayBackDlg::OnEraseBkgnd(CDC* pDC)

{

//return CDialog::OnEraseBkgnd(pDC);

      return TRUE;       

}

        

从上面的代码可以看出,双缓冲使用一个位图对象CBitmap memBmp 作为绘图数据的存储对象,CBitmap *pOldBmp=memDC.SelectObject(&memBmp);将绘图操作的对象memDC和绘图数据的存储对象memBmp关联起来,在后续过程中使用memDC进行的绘图操作的绘图数据都会存储到memBmp中,它实质上是一个位图图像,最后用

pDC->BitBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY);

将这个位图图像应用到设备环境中

 

 

3.局部重绘

         假如一个窗口上既有需要进行重复绘图的区域,又有一些不需要进行重复绘图的区域,如果再每个绘图周期都没有区别的对整个窗口进行重绘,这是很没有必要的,这里可以只对需要进行重复绘图的局部区域进行重绘。

         进行局部重绘可以通过CDC类函数

BOOL BitBlt(

   int x,

   int y,

   int nWidth,

   int nHeight,

   CDC* pSrcDC,

   int xSrc,

   int ySrc,

   DWORD dwRop

);

里的第14个参数进行指定,这四个参数指定了一个矩形,程序会将内存中的数据应用到这个设备所在环境的这个矩形上,实质上就是将绘图后生成的图像拷贝到窗口的指定区域进行显示。

       指定了这4个参数后,确实是可以实现局部重绘的功能了,但是对于那些在这个区域之外的界面在整个窗口丢失焦点(如,被其他程序窗口覆盖后又获得焦点)的情况,它们不会被重新绘制。这个问题的原因是我们在OnEraseBkgnd函数中没有区别的只返回一个TRUE,把它自带的这句代码

return CDialog::OnEraseBkgnd(pDC);

给注释掉了,函数

afx_msg BOOL OnEraseBkgnd(

   CDC* pDC

);

的功能是准备一个失效的区域进行重绘,重绘的过程是使用窗口类的背景画刷进行,它的功能是通知程序进行整个窗口的重绘。所以在这种情况下,我们需要调用CDialog::OnEraseBkgnd(pDC)进行整个窗口重绘。

 

大致的操作流程是:

<1>将所有的绘图操作全部放到OnPaint函数当中

void CPlayBackDlg::OnPaint()

{ 

   if(m_bChartDataInit)DrawChart(); 

   CDialog::OnPaint();

}

 

 

<2>OnEraseBkgnd里对绘图操作的情况进行区分

BOOL CPlayBackDlg::OnEraseBkgnd(CDC* pDC)

{

   if(m_bDrawChart)

      return TRUE;

   else

      return CDialog::OnEraseBkgnd(pDC);

}

 

作者:kfqcome 发表于2011-6-16 16:37:00 原文链接
阅读:16 评论:0 查看评论

转载于:https://www.cnblogs.com/kfqcome/archive/2011/06/16/2137003.html

相关文章:

  • 【转载】Linux下进程的建立
  • SQL SERVER2005几个性能优化综述
  • windows phone7 mango 多人在线游戏
  • ISAG短信上下行的纠结
  • ASP.NET MVC3书店--第三节 视图与视图模型(转)
  • ASP.NET Session丢失问题原因及解决方案
  • SetWaitableTimer 通过异步程序调用(APC)实现的定时功能
  • C#扩展和收缩代码
  • Activity的taskAffinity属性
  • C# Winform利用POST传值方式模拟表单提交数据(Winform与网页交互)
  • Oracle Namespace 说明
  • linux目录配置 FHS
  • 排除软件缺陷的两种重要手段
  • 我收藏了 NHibernate之旅系列文章导航
  • 首篇文章测试。
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • Docker 笔记(2):Dockerfile
  • extract-text-webpack-plugin用法
  • Java程序员幽默爆笑锦集
  • Linux链接文件
  • SOFAMosn配置模型
  • XML已死 ?
  • 复习Javascript专题(四):js中的深浅拷贝
  • 技术胖1-4季视频复习— (看视频笔记)
  • 实习面试笔记
  • 使用 @font-face
  • 一份游戏开发学习路线
  • 在weex里面使用chart图表
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • ​3ds Max插件CG MAGIC图形板块为您提升线条效率!
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • #Linux(权限管理)
  • #NOIP 2014# day.1 T2 联合权值
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (c语言版)滑动窗口 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度
  • (补)B+树一些思想
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (十)T检验-第一部分
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • (转载)VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
  • .net core 源码_ASP.NET Core之Identity源码学习
  • .NET 反射 Reflect
  • .Net6 Api Swagger配置
  • ??如何把JavaScript脚本中的参数传到java代码段中
  • [ 云计算 | AWS 实践 ] 基于 Amazon S3 协议搭建个人云存储服务
  • [Angular] 笔记 6:ngStyle
  • [BZOJ]4817: [Sdoi2017]树点涂色
  • [c#基础]值类型和引用类型的Equals,==的区别
  • [c++] 自写 MyString 类
  • [C++]18:set和map的使用
  • [CLickhouse] 学习小计
  • [Docker]五.Docker中Dockerfile详解