MFC编程,Cview类OnDraw重绘时,视图内容消失问题的解决
来源:互联网 发布:常州巨人网络待遇 编辑:程序博客网 时间:2024/05/19 14:17
问题描述:在进行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 defaultCLocateByLhDoc *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_bmpBufdcMem.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等很具有特性,对问题的解决造成了很大的困扰,通过在代码的调试中不断的摸索才渐渐熟悉了这些特性,进而解决问题。代码肯定存在不完善的地方,希望大家能给予指正,共同进步!
0 0
- MFC编程,Cview类OnDraw重绘时,视图内容消失问题的解决
- 关于MFC OnDraw重绘时画面闪烁问题的解决
- MFC,VC++中,CView类意外消失
- MFC修改视图CView的背景颜色
- MFC修改视图CView的背景颜色
- MFC 视图类(CView)介绍
- CView中OnDraw( )的调用
- MFC classview类视图消失的解决办法
- CView类突然消失
- MFC classview类视图消失的解决办法 以及 一些常见的VC 2B问题
- MFC classview类视图消失的解决办法||一些常见的VC 2B问题
- MFC视图窗口(CView子类)初始化消息的调用顺序
- [MFC]CView视图类、CMainFrame主框架类
- 视图类(CView)的三个子类
- 视图类CView
- CView视图类
- mfc类视图中view类消失的解决办法
- MFC中视图类的OnDraw与OnPaint两个函数的区别
- 角度与弧度间的关系
- Mysql中事务隔离级别与binlog_format的一点理解
- word2007如何实现将正文字体全部改成其它的大小
- java高分局之JVM命令参数大全(标准选项)
- iOS UITextView以设置边距
- MFC编程,Cview类OnDraw重绘时,视图内容消失问题的解决
- CodeForces 486C Palindrome Transformation(贪心)
- Core Data概述
- WP8移植过程遇到的各种坑
- HTML学习笔记-v1.3
- [html][css]我的编码习惯
- 黑马程序员学习日记--IO流技术(二)
- ios开发:zxing 二维码
- JavaScript 的性能优化:加载和执行