Invalidate()InvalidateRect()UpdateWindow()三者的区别

Invalidate():不立即更新。作用区域是整个窗口客户区,将客户区标记为无效,并将WM_PAINT放到消息队列中。

InvalidateRect():立即更新。作用区域是指定矩形区,绕过消息队列直接将WM_PAINT发往窗口对象,并立即执行WM_PAINT

UpdateWindow():立即更新。作用区域是整个窗口客户区,先判断客户区是否存在无效区域,若有无效区域,则绕过消息队列直接将WM_PAINT发往窗口对象,并立即执行WM_PAINT;若没有无效区域,返回,不执行任何操作。

 

详细说明如下:

void Invalidate( BOOL bErase = TRUE );

void InvalidateRect( LPCRECT lpRect, BOOL bErase = TRUE );

void UpdateWindow( );

这是三个函数的原函数。前两个函数中有个参数bErase,表示否要在WM_PAINT消息前发送WN_ERASEBKGND。

若为TRUE,发送;从而调用WN_ERASEBKGND来擦除一次背景,也就是用背景色将所选区域覆盖一次

若为FALSE,不发送,不进行背景的擦除,也就是不用背景色覆盖,直接在当前区域绘制。

 

关于OnEraseBkgnd():

afx_msg BOOL OnEraseBkgnd( CDC*pDC );

当CWnd对象的背景需要被擦除时(例如,当窗口大小被改变时),框架就调用这个函数。它被调用以便为绘图准备无效区域。

返回值的具体含义是:

TRUE表示系统会在你画之前用背景色将所选区域覆盖一次,默认背景色为白色,可以通过设置BRUSH来改变背景色。

FALSE表示画之前不用背景色覆盖,直接绘制。

所以为了提高效率和消除闪烁,一般取值为FALSE。

 

OnEraseBkgnd是在窗口大小发生改变等情况下发生的,它将绘制窗口背景;

OnCtlColor是当窗口的控件需要绘制时发生的,它将绘制窗口的控件。

调用时机:

OnEraseBkgnd :在窗口背景需要重绘时调用.

OnPaint : 此时OnEraseBkgnd已经调用过了,所以在此响应函数体内对背景进行的操作将覆盖OnEraseBkgnd中所做的操作.

OnCtlColor : 由于在窗口将要被(第一次)绘制时响应,子窗口可以通过发送WM_CTLCOLOR请求父窗口传来一个HBRUSH.

 

Invalidate():标记一个需要重绘的无效区域,并将一个WM_PAINT放到消息队列中,但是并不立即重绘,这是因为WM_PAINT消息的优先级很低,必须等到系统执行WM_PAINT时进行重绘。这一点类似PostMessage(WM_PAINT)。若Invalidate之后还有其他的语句正在执行,程序没有机会去处理WM_PAINT消息,但当函数执行完毕后,消息处理才得以进行。所以不管Invalidate放在函数哪里,都是函数最后执行的。

InvalidateRect(hWnd,&rect,TRUE);作用对象是窗口的指定区域。无论窗口客户区是否无效,都向hWnd窗体发出WM_PAINT的消息,强制客户区域重绘制因为是绕过消息队列直接向客户区窗口发送WM_PAINT消息,所以客户区会立刻执行WM_PAINT消息来进行重绘。rect是你指定要刷新的区域,此区域外的客户区域不被重绘,这样防止客户区域的一个局部的改动,而导致整个客户区域重绘而导致闪烁,如果最后的参数为TRUE,则还向窗体发送WM_ERASEBKGND消息,使背景重绘,执行顺序是WM_ERASEBKGND->WM_PAINT

UpdateWindow()的作用对象是窗口的整个客户区。该函数也是绕过消息队列直接向客户区窗口发送WM_PAINT消息,并且只向窗体发送WM_PAINT消息。但在发送之前会调用GetUpdateRect(hWnd,NULL,TRUE)来判断看有无可绘制的客户区域,如果没有,则不发送WM_PAINT消息。只要客户区有一部分是无效的,UpdateWindow()就会导致整个客户区的重绘。注意UpdateWindow()并不会导致窗口客户区无效,若窗口客户区都是有效的,那么调用UpdateWindow()并不会引起重绘操作。

 

如果希望立即重绘客户区,可以在调用Invalidate()之后调用UpdateWindow(),这样Invalidate()就会令窗口客户区无效,并将WM_PAINT消息发往消息队列。然后UpdateWindow()的调用会导致WM_PAINT立即调用,从而重绘客户区。

即:

Invalidate(False);

UpdateWindow();

等效于

InvalidateRect(hWnd,NULL,False);

 

如果客户区的任一部分无效,则UpdateWindow()将导致WindowsWM_PAINT消息调用窗口过程(如果整个客户区有效,则不调用窗口过程)。这一WM_PAINT消息不进入消息队列,直接由WINDOWS调用窗口过程。窗口过程完成刷新以后立刻退出,WINDOWS将控制返回给程序中UpdateWindow()调用之后的语句。

 

UpdateData()用于控件和变量的更新。

参数为:

TRUE:控件>变量(将控件上显示的数据更新到控件内的变量中,用于输入)

FALSE:变量->控件(将控件内的变量更新到控件的输出显示上,用于输出显示)

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值