先看一段移动图片的程序:

绘图工作都在ReDraw()中

响应MouseMove  改变图片的位置,鼠标移动后需要重绘窗口

实验一: ReDraw()在MouseMove函数中调用

[html] view plaincopy print?
  1. OnMouseMove(UINT nFlags, CPoint point)
  2. {
  3. 。。。
  4. ReDraw();
  5. InvalidateRect(m_ClientRect);
  6. 。。。
  7. }
OnMouseMove(UINT nFlags, CPoint point)
{。。。ReDraw();InvalidateRect(m_ClientRect); 。。。
}
[html] view plaincopy print?
  1. 试验发现: 鼠标移动时,图片移动不连贯,也就是说窗口没有实时重绘,而是每隔不定的时间重绘一次,这样图片移动时给人磕磕绊绊、很不顺畅的感觉。
试验发现: 鼠标移动时,图片移动不连贯,也就是说窗口没有实时重绘,而是每隔不定的时间重绘一次,这样图片移动时给人磕磕绊绊、很不顺畅的感觉。

试验二: ReDraw()在OnDraw函数中调用

[html] view plaincopy print?
  1. OnDraw(CDC* pDC)
  2. {
  3. ...
  4. ReDraw();
  5. ...
  6. }
OnDraw(CDC* pDC)
{...ReDraw();...
}
[html] view plaincopy print?
  1. OnMouseMove(UINT nFlags, CPoint point)
  2. {
  3. 。。。
  4. //ReDraw();  注释掉ReDraw(),仅使用InvalidateRect()
  5. InvalidateRect(m_ClientRect);
  6. 。。。
  7. }
OnMouseMove(UINT nFlags, CPoint point)
{。。。//ReDraw();  注释掉ReDraw(),仅使用InvalidateRect()InvalidateRect(m_ClientRect);    。。。
}

试验发现:图片能够随鼠标实时移动,也就是说窗口得到了实时更新

那问题自然就来了:为什么两个试验,结果迥然?

要说InvalidateRect()不能马上更新窗口,那为什么试验二的效果看起来如立即更新一样?

据我分析,可能的原因是这样的:

首先,InvalidateRect()不能马上更新窗口,而是将更新消息WM_PAINT放在消息队列中,在实验二中,消息队列中的消息很少,所以很快便执行到了WM_PAINT,而实验一中,在InvalidateRect()之前还要执行ReDraw(),执行ReDraw()需要一段时间,这段时间,因为鼠标一直移动,所以一直将鼠标移动消息放入消息队列中,因此,WM_PAINT前的消息多,所以便出现了图片移动不连贯的现象。

试验三 :ReDraw()放入MouseMOVE函数中 使用UpDateWindow()

[cpp] view plaincopy print?
  1. OnMouseMove(UINT nFlags, CPoint point)
  2. {
  3. 。。。
  4. ReDraw();
  5. UpdateWindow();
  6. 。。。
  7. }
OnMouseMove(UINT nFlags, CPoint point)
{。。。ReDraw();UpdateWindow();。。。
}

按相关资料说:UpdateWindow()可以立即更新窗口,那么这下应该没有问题了吧!

可是,试验显示,鼠标移动时,图片稳如磐石,丝毫不动。而只有窗口最小化然后最大化需要重绘时,图片才显示到鼠标所在的位置

怎么回事?怎么回事呀,资料上不是说UpdateWindow()立即更新窗口吗?怎么试验结果好像差之千里。。。

别急: 先找找原因。

诚然,UpdateWindow() 可以实现立即更新,但是它是有前提的。

什么?没找到前提条件?只看到资料说立即更新?---------这就是不完善的资料造成的后果

额。。。-----还有一种就是明明资料上有介绍,是自己忽视了

UpdateWindow() 可以实现立即更新,但是它的前提是:先让需要更新的区域失效。

试验四: 使用UpdateWindow()更新窗口

[cpp] view plaincopy print?
  1. OnMouseMove(UINT nFlags, CPoint point)
  2. {
  3. 。。。
  4. ReDraw();
  5. InvalidateRect(m_ClientRect); //先将需要更新的区域 用InvalidateRect失效掉,然后再UpdateWindow()
  6. UpdateWindow();
  7. 。。。
  8. }
OnMouseMove(UINT nFlags, CPoint point)
{。。。ReDraw();InvalidateRect(m_ClientRect); //先将需要更新的区域 用InvalidateRect失效掉,然后再UpdateWindow() UpdateWindow();。。。
}

结果显示: 图片移动连贯,可以实现立即更新

试验五: 使用RedrawWindow()

[cpp] view plaincopy print?
  1. OnMouseMove(UINT nFlags, CPoint point)
  2. {
  3. 。。。
  4. ReDraw();
  5. RedrawWindow(m_ClientRect);
  6. 。。。
  7. }
OnMouseMove(UINT nFlags, CPoint point)
{。。。ReDraw();RedrawWindow(m_ClientRect);。。。
}

结果显示:图片移动连贯,可以立即更新窗口

RedrawWindow(m_ClientRect); 效果相当于InvalidateRect(m_ClientRect); UpdateWindow();

[cpp] view plaincopy print?
  1. BOOL RedrawWindow(LPCRECT lpRectUpdate = NULL,
  2. CRgn* prgnUpdate = NULL,
  3. UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
 BOOL RedrawWindow(LPCRECT lpRectUpdate = NULL,CRgn* prgnUpdate = NULL,UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);

这是 RedrawWindow()的定义,由此得知:默认参数情况下是立即更新窗口

RedrawWindow(rect) 相当于:

[cpp] view plaincopy print?
  1. RedrawWindow(m_ClientRect,NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
         RedrawWindow(m_ClientRect,NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);

总结:

由以上五个例子分析了三者之区别,简言之,InvalidateRect()不能实现立即更新 ,

但是InvalidateRect()与 UpdateWindow()结合后可以实现立即更新,

两者结合的效果相当于RedrawWindow(rect)

InvalidateRect()、UpdateWindow()、RedrawWindow()区别相关推荐

  1. 【转】VC窗口刷新InvalidateRect和UpdateWindow RedrawWindow

    首先说说WM_PAINT 这个重要的消息: The WM_PAINT message is generated by the system and should not be sent by an a ...

  2. 窗口刷新 Invalidate UpdateWindow RedrawWindow

    窗口刷新的几个函数:InvalidateUpdateWindowRedrawWindow 一:什么时候才会发生重绘窗口的消息?        当需要更新或重新绘制窗口的外观时,应用程序就会发送WM_P ...

  3. 吕鑫MFC学习系列六

    这一章学习的相关知识框架: 一.根据主窗口类型,MFC软件工程可以分为以下几种架构模型: 1.SDI(Single Document Interface):单文档界面,一个主框架窗口下只能编辑一份文档 ...

  4. Window 32位 编程总结

    Lesson01 win32 Window 32位 编程 1.Windows编程基础 2.Windows的字符 3.窗口处理 4.消息处理 5.绘图 6.对话框 7.控件 Win32编程: Windo ...

  5. 【转】关于OnPaint的工作机制

    转载出处:http://blog.csdn.net/foreverhuylee/article/details/21889025 用了两年的VC++,其实对OnPaint的工作原理一直都是一知半解.这 ...

  6. 结合本科C++项目的MFC学习总结

    MFC学习笔记 个人财务管理软件设计中MFC控件的使用(List) list control控件的使用 combo box控件的使用 文件保存 登录对话框的建立 问题-MFC读取文件在EditCont ...

  7. 绘图用的函数及矩形类CRect和矩形结构RECT

    绘图一般在视图类的(屏幕/打印机)绘图消息响应函数OnDraw中进行,例如: void CTestView::OnDraw(CDC* /pDC/) { CTestDoc* pDoc = GetDocu ...

  8. invalidate

    转载请注明出处:                前言: 本文是我读<Android内核剖析>第13章----View工作原理总结而成的,在此膜拜下作者 .同时真挚地向渴望了解      A ...

  9. MiniGUI细节处理(转)

    MiniGUI编程--列表框 分类: minigui2009-11-04 20:40 列表框 LBS(ListBoxStyle) 以CTRL_LIST/"list"为类名调用Cre ...

最新文章

  1. leetcode网学习笔记(1)
  2. tcpdump基础教程
  3. Android系统的架构
  4. linux安装软件不同用户名密码,Linux的安装和基本命令
  5. Dockerfile使用方法详解
  6. 双色球随机选号器界面设计及功能实现
  7. 简述osi参考模型各层主要功能_计软考研双日练 | OSI参考模型各层提供什么服务?...
  8. jsp标签 判断 余数_程序员的数学基础课(三)余数与迭代法
  9. dubbo学习之事件通知实践
  10. 智能玩具 数据采集 首页展示 注册 登录 自动登录 二维码图片
  11. python翻译matlab,如何在python3中翻译MATLAB单元?
  12. Bailian1833 POJ1833 排列【全排列】
  13. 学了N年英语,你学会翻译了吗?——最基本的数据库连接
  14. Google GPS在Android上的一些应用
  15. 同义句转换在线翻译器的软件
  16. 445端口的简单利用
  17. 工具分享之NetSetMan
  18. ef 数据迁移mysql_ef数据库迁移
  19. Polish calculation
  20. 【FPGA——工具篇】32个FPGA开源网站

热门文章

  1. c语言在管理系统中的应用,C语言应用——学生管理系统的制作
  2. Spring Boot的学习之路(03):基础环境搭建,做好学习前的准备工作
  3. 实战ELK(5) Logstash 入门
  4. 中间件及tomcat的内存溢出调优
  5. ubuntu将GNU nano换成vim
  6. 如何迁移完整SQL数据库到另外一台服务器
  7. 实用ExtJS教程100例-002:MessageBox的三种用法
  8. Linux Shell 下载网站指定文件
  9. BASIC-1_蓝桥杯_闰年判断
  10. 【深度学习】词的向量化表示