热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MFC编程,Cview类OnDraw重绘时,视图内容消失问题的解决

问题描述:在进行MFC绘图编程时(以简单的绘制线条为例),视图窗口的大小变化会引起调用OnDraw()。默认的OnDraw()会重绘显示出一个空白的视图,因此必须重写这个方法以显

      问题描述:在进行MFC绘图编程时(以简单的绘制线条为例),视图窗口的大小变化会引起调用OnDraw()。默认的OnDraw()会重绘显示出一个空白的视图,因此必须重写这个方法以显示文档的视图。

   解决思路:通过查阅资料发现,这种问题通常的处理方法是在文档中记录绘图数据,在窗口重绘时使用这些数据恢复图像。我认为使用这种方法时,在绘图的同时考虑记录数据将增加不少代码复杂度(因我了解的不够及水平有限,这种观点可能有误),同时在复杂的图像所需要记录的数据量将很大。另外,还有一种“内存缓存画图”的方式,考虑到MFC时 文档/视图 类,视图CView负责数据的显示和修改,文档CDocument类负责数据的存储和加载,从而把数据管理和显示方法分离开来。我们在CDocument类中添加一个CBitMap对象,将每次中间绘图时的客户区的内容保存成BitMap,当所有的操作都执行好以后,将最终的BitMap拷贝到屏幕中,这就是所谓的内存缓存画图方式。我比较倾向于用这种方式解决重绘问题,但我所查到的网上所提供的代码都只能解决绘图时的“闪烁”问题(参考搜索“C++双缓冲绘图”)。因此我基于后者的缓冲绘图思想,以绘制线条为例,编写代码解决重绘问题。
具体实现过程及代码如下(工程名为LocateByLh):
1、在CLocateByLhDoc类中创建CBitmap类型的m_bmpBuf用于保存视图(同时也可以用于缓冲绘图),同时在CLocateByLhView类中添加一个bool型变量。
public:  CBitmap m_bmpBuf; 
/////////////////////////
private:  bool bFlag; 
/////////////////////////
2、在OnDraw()方法内添加m_bmpBuf输出代码和只在首次执行的m_bmpBuf初始化代码(设置bFlag就是为了只执行一次)。
void CLocateByLhView::OnDraw(CDC* pDC){  CLocateByLhDoc* pDoc = GetDocument();  ASSERT_VALID(pDoc);  // TODO: add draw code for native data here
 //重绘显示bitmap,思路是创建一个临时的dcMem,先把m_bmpBuf作为画布放入其中,然后拷贝到pDC中显示出来
 CDC dcMem;  CRect rect;  GetClientRect(&rect);  dcMem.CreateCompatibleDC(NULL);  dcMem.SelectObject(&pDoc->m_bmpBuf);  pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,SRCCOPY);  dcMem.DeleteDC();
 //初始化一个白色填充的m_bmpBuf,
 if(bFlag){  CLocateByLhDoc *pDoc = GetDocument();  CDC dcMem2;  dcMem2.CreateCompatibleDC(NULL);  pDoc->m_bmpBuf.CreateCompatibleBitmap(pDC,2500,1500);  dcMem2.SelectObject(&pDoc->m_bmpBuf);  dcMem2.FillSolidRect(0,0,2500,1500,RGB(255,255,255));  dcMem2.BitBlt(0,0,rect.Width(),rect.Height(),pDC,0,0,SRCCOPY);  dcMem2.DeleteDC();  bFlag=false;  } } 
 
 
 
 
3、鼠标左键弹起事件中的绘图线条代码,
void CLocateByLhView::OnLButtonUp(UINT nFlags, CPoint point)  {  // TODO: Add your message handler code here and/or call default    CLocateByLhDoc *pDoc = GetDocument();  CDC* pDC = GetDC();  CDC dcMem;  CRect rect;  GetClientRect(&rect);  dcMem.CreateCompatibleDC(NULL);
  //注释部分采用的是非缓冲画图,直接用pDC进行绘图,然后复制到m_bmpBuf  //CPen pen(PS_SOLID,2,RGB(255,0,0));  //pDC->SelectObject(&pen);  //pDC->MoveTo(m_ptOrigin);  //pDC->LineTo(point);  //dcMem.SelectObject(&pDoc->m_bmpBuf);
 //dcMem.BitBlt(0,0,rect.Width(),rect.Height(),pDC,0,0,SRCCOPY); 
 
 //在虚拟的dcMem中绘图,然后一次性输出显示,同时更新了m_bmpBuf  dcMem.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);  dcMem.SelectObject(&pDoc->m_bmpBuf);  dcMem.MoveTo(m_ptOrigin);//绘制线条代码  dcMem.LineTo(point);//绘制线条代码  pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,SRCCOPY);     dcMem.DeleteDC();  ReleaseDC(pDC);    CView::OnLButtonUp(nFlags, point); } 
总结:
代码中所涉及的函数如BitBlt,FillSolidRect等很具有特性,对问题的解决造成了很大的困扰,通过在代码的调试中不断的摸索才渐渐熟悉了这些特性,进而解决问题。代码肯定存在不完善的地方,希望大家能给予指正,共同进步!



推荐阅读
  • 初识java关于JDK、JRE、JVM 了解一下 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • 达人评测 酷睿i5 12450h和锐龙r7 5800h选哪个好 i512450h和r75800h对比
    本文介绍了达人评测酷睿i5 12450h和锐龙r7 5800h选哪个好的相关知识,包括两者的基本配置和重要考虑点。希望对你在选择时提供一定的参考价值。 ... [详细]
  • Java图形化计算器设计与实现
    本文介绍了使用Java编程语言设计和实现图形化计算器的方法。通过使用swing包和awt包中的组件,作者创建了一个具有按钮监听器和自定义界面尺寸和布局的计算器。文章还分享了在图形化界面设计中的一些心得体会。 ... [详细]
  • mysqldinitializeconsole失败_mysql03误删除了所有用户解决办法
    误删除了所有用户解决办法第一种方法(企业常用)1.将数据库down掉[rootdb03mysql]#etcinit.dmysqldstopShuttingdownMySQL..SU ... [详细]
  • android 触屏处理流程,android触摸事件处理流程 ? FOOKWOOD「建议收藏」
    android触屏处理流程,android触摸事件处理流程?FOOKWOOD「建议收藏」最近在工作中,经常需要处理触摸事件,但是有时候会出现一些奇怪的bug,比如有时候会检测不到A ... [详细]
  • 这个问题困扰了我两天,卸载Dr.COM客户端(我们学校上网要装这个客户端登陆服务器,以后只能在网页里输入用户名和密码了),问题解决了。问题的现象:在实验室机台式机上安装openfire和sp ... [详细]
  • 近来有一个需求,是需要在androidjava基础库中插入一些log信息,完成这个工作需要的前置条件有编译好的android源码具体android源码如何编译,这 ... [详细]
  • 【CTF 攻略】第三届 SSCTF 全国网络安全大赛—线上赛 Writeup
    【CTF 攻略】第三届 SSCTF 全国网络安全大赛—线上赛 Writeup ... [详细]
author-avatar
YOYO很快乐的傻瓜
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有