VC++重绘消息

VC++重绘消息

创建、移动窗口,改变窗口大小,这些操作会调用

严格地说,只有当收到WM_PAINT消息后窗口会重绘,而引起这个消息的事件有很多,比如:首次创建 窗口,移动或者覆盖窗口,改变窗口大小等

Invalidate()标记一个需要重绘的无效区域,如果您Invalidate()之后还有其他的语句正在执行,程序没有机会去处理WM_PAINT消息,只有当函数执行完毕后,消息处理才得以进行。

Invalidate():
​ 该函数的作用是使整个窗口客户区无效。窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口,那么原来被遮住的部分就是无效的,需要重绘。这时Windows会在应用程序的消息队列中放置WM_PAINT消息。MFC为窗口类提供了WM_PAINT的消息处理函数OnPaint,OnPaint负责重绘窗口。视图类有一些例外,在视图类的OnPaint函数中调用了OnDraw函数,实际的重绘工作由OnDraw来完成。参数bErase为TRUE时,重绘区域内的背景将被擦除,否则,背景将保持不变。

  • 当第一次创建一个窗口时,
  • 当改变窗口的大小时,
  • 当把窗口从另一个窗口背后移出时,
  • 当最大化或最小化窗口时,等等

当需要主动引发窗口中的绘制操作,比如当窗口显示的数据改变的时候,一般可通过下面方式实现:

  • void Invalidate( BOOL bErase = TRUE ); //使整个客户区窗口无效
  • void InvalidateRect( LPCRECT lpRect, BOOL bErase = TRUE ); //使指定矩形区域窗口无效

Invalidat最后也是调用InvalidatRect,在windows API里只有InvalidatRect的

UpdateWindow():
​ UpdateWindow( )的作用是使窗口立即重绘。调用Invalidate等函数后窗口不会立即重绘,这是由于WM_PAINT消息的优先级很低,它需要等消息队列中的其它消息发送完后才能被处理。调用UpdateWindow函数可使WM_PAINT被直接发送到目标窗口,从而导致窗口立即重绘。

当第一次创建一个窗口时,当改变窗口的大小时,当把窗口从另一个窗口背后移出时,当最大化或最小化窗口时等等,操作系统会发送WM_PAINT消息。
当需要主动引发窗口中的绘制操作,可通过下面方法实现:
调用Invalidate使整个客户区窗口无效、调用InvalidatRect使指定矩形区域窗口无效从而产生WM_PAINT消息,但Invalidate最后也是调用InvalidatRect,因为在windows API里只有InvalidatRect;
调用Invalidate等函数后窗口不会立即重绘,这是由于WM_PAINT消息的优先级很低,它需要等消息队列中的其它消息发送完后才能被处理,这时可调用UpdateWindow,
UpdateWindow判断是否有无效区,有则马上sending a WM_PAINT message到窗口过程,此时的WM_PAINT消息不用进入消息队列排队。
RedrawWindow具有Invalidate和UpdateWindow的双特性:声明窗口的状态为无效,立即发送WM_PAINT到窗口过程并立即更新窗口。

窗体在刷新重绘时,总是先用背景色将显示区清除,然后调用OnPaint,而背景色往往与绘图内容反差很大,这样一擦一写会造成图象颜色的反差。当WM_PAINT的响应很频繁的时候,这种反差也越发明显,也就会出现闪烁现象(如果将背景刷设置成NULL,虽然重绘图形不会闪,但窗口显示会一团糟,解决:

  1. 用InvalidateRect函数只重绘部分区域,而且不重绘背景(最后一个参数设为FALSE)就可以解决大部分的屏闪问题。
  2. 使用BitBlt函数。先在内存中作图,然后用此函数将做好的图复制到前台,同时禁止背景刷新,这样就消除了闪烁(双缓冲绘图:在内存中创建与画布一致的缓冲区->在缓冲区画图->将缓冲区位图拷贝到当前画布上->释放内存缓冲区。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值