InvalidateRect()、UpdateWindow()、RedrawWindow()区别

来源:互联网 发布:php 判断是否含有中文 编辑:程序博客网 时间:2024/05/28 16:25
先看一段移动图片的程序:

  

   绘图工作都在ReDraw()中

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

 

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

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

 

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

 

[html] view plain copy
print?
  1. OnDraw(CDC* pDC)  
  2. {  
  3.   
  4. ...  
  5.     ReDraw();  
  6.   
  7. ...  
  8. }  


 

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

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

 

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

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

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

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

 

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

 

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


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

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

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

 

别急: 先找找原因。

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

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

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

 

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

 

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

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


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

 

试验五: 使用RedrawWindow()

 

 

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


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

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

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


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

RedrawWindow(rect) 相当于:

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


总结: 

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

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

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

阅读全文
0 0
原创粉丝点击