InvalidateRect 和validateRect 和wm_paint
2011-05-22 20:17
316 查看
今天复习了下windows程序设计五第9章节,想到了个问题:
case WM_PAINT :
InvalidateRect (hwnd, &rect, TRUE) ;
hdc = BeginPaint (hwnd, &ps) ;
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
SetBkMode (hdc, TRANSPARENT) ;
TextOut (hdc, 24 * cxChar, cyChar, szTop, lstrlen (szTop)) ;
TextOut (hdc, 24 * cxChar, cyChar, szUnd, lstrlen (szUnd)) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DRAWITEM :
case WM_COMMAND :
ScrollWindow (hwnd, 0, -cyChar, &rect, &rect) ;
hdc = GetDC (hwnd) ;
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
TextOut (hdc, 24 * cxChar, cyChar * (rect.bottom / cyChar - 1),
szBuffer,
wsprintf (szBuffer, szFormat,
message == WM_DRAWITEM ? TEXT ("WM_DRAWITEM") :
TEXT ("WM_COMMAND"),
HIWORD (wParam), LOWORD (wParam),
HIWORD (lParam), LOWORD (lParam))) ;
ReleaseDC (hwnd, hdc) ;
ValidateRect (hwnd, &rect) ;
break ;
为什么要用validaterect这个函数呢。查了查,跳到windows程序设计五第2章节,有了答案
发生下面几种事件之一时,窗口消息处理程序会接收到一个WM_PAINT消息:
在使用者移动窗口或显示窗口时,窗口中先前被隐藏的区域重新可见。
使用者改变窗口的大小(如果窗口类别样式有着CS_HREDRAW和CS_VREDRAW位旗标的设定)。
程序使用ScrollWindow或ScrollDC函数滚动显示区域的一部分。
程序使用InvalidateRect或InvalidateRgn函数刻意产生WM_PAINT消息。
OK,很明显ScrollWindow会产生一个WM_PAINT消息,那么 case WM_DRAWITEM:
case WM_COMMAND:中的TextOut不就被覆盖了!!,继续看下去
尽管窗口消息处理程序一旦接收到WM_PAINT消息之后,就准备更新整个显示区域,但它经常只需要更新一个较小的区域(最常见的是显示区域中的矩形区域)。显然,当对话框覆盖了部分显示区域时,情况即是如此。在擦除对话框之后,需要重画的只是先前被对话框遮住的矩形区域。
这个区域称为「无效区域」或「更新区域」。正是显示区域内无效区域的存在,才会让Windows将一个WM_PAINT消息放在应用程序的消息队列中。只有在显示区域的某一部分失效时,窗口才会接受WM_PAINT消息。
Windows内部为每个窗口保存一个「绘图信息结构」,这个结构包含了包围无效区域的最小矩形的坐标以及其它信息,这个矩形就叫做「无效矩形」,有时也称为「无效区域」。如果在窗口消息处理程序处理WM_PAINT消息之前显示区域中的另一个区域变为无效,则Windows计算出一个包围两个区域的新的无效区域(以及一个新的无效矩形),并将这种变化后的信息放在绘制信息结构中。Windows不会将多个WM_PAINT消息都放在消息队列中。
窗口消息处理程序可以通过呼叫InvalidateRect使显示区域内的矩形无效。如果消息队列中已经包含一个WM_PAINT消息,Windows将计算出新的无效矩形。否则,它将一个新的WM_PAINT消息放入消息队列中。在接收到WM_PAINT消息时,窗口消息处理程序可以取得无效矩形的坐标(我们马上就会看到这一点)。通过呼叫GetUpdateRect,可以在任何时候取得这些坐标。
在处理WM_PAINT消息处理期间,窗口消息处理程序在呼叫了BeginPaint之后,整个显示区域即变为有效。程序也可以通过呼叫ValidateRect函数使显示区域内的任意矩形区域变为有效。如果这呼叫具有令整个无效区域变为有效的效果,则目前队列中的任何WM_PAINT消息都将被删除。
现在很明白了,validaterect能使所有的无效区域变为有效,则消息队列中WM_PAINT消息被删除了,当然不会响应了。
所以在重载WM_ONPAINT,它默认会生成一个CPaintDC dc(this);,不要以为这只是一个初始化,就直接把它干掉,这样你的所有整个显示区域就一直无效了.
case WM_PAINT :
InvalidateRect (hwnd, &rect, TRUE) ;
hdc = BeginPaint (hwnd, &ps) ;
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
SetBkMode (hdc, TRANSPARENT) ;
TextOut (hdc, 24 * cxChar, cyChar, szTop, lstrlen (szTop)) ;
TextOut (hdc, 24 * cxChar, cyChar, szUnd, lstrlen (szUnd)) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DRAWITEM :
case WM_COMMAND :
ScrollWindow (hwnd, 0, -cyChar, &rect, &rect) ;
hdc = GetDC (hwnd) ;
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
TextOut (hdc, 24 * cxChar, cyChar * (rect.bottom / cyChar - 1),
szBuffer,
wsprintf (szBuffer, szFormat,
message == WM_DRAWITEM ? TEXT ("WM_DRAWITEM") :
TEXT ("WM_COMMAND"),
HIWORD (wParam), LOWORD (wParam),
HIWORD (lParam), LOWORD (lParam))) ;
ReleaseDC (hwnd, hdc) ;
ValidateRect (hwnd, &rect) ;
break ;
为什么要用validaterect这个函数呢。查了查,跳到windows程序设计五第2章节,有了答案
发生下面几种事件之一时,窗口消息处理程序会接收到一个WM_PAINT消息:
在使用者移动窗口或显示窗口时,窗口中先前被隐藏的区域重新可见。
使用者改变窗口的大小(如果窗口类别样式有着CS_HREDRAW和CS_VREDRAW位旗标的设定)。
程序使用ScrollWindow或ScrollDC函数滚动显示区域的一部分。
程序使用InvalidateRect或InvalidateRgn函数刻意产生WM_PAINT消息。
OK,很明显ScrollWindow会产生一个WM_PAINT消息,那么 case WM_DRAWITEM:
case WM_COMMAND:中的TextOut不就被覆盖了!!,继续看下去
尽管窗口消息处理程序一旦接收到WM_PAINT消息之后,就准备更新整个显示区域,但它经常只需要更新一个较小的区域(最常见的是显示区域中的矩形区域)。显然,当对话框覆盖了部分显示区域时,情况即是如此。在擦除对话框之后,需要重画的只是先前被对话框遮住的矩形区域。
这个区域称为「无效区域」或「更新区域」。正是显示区域内无效区域的存在,才会让Windows将一个WM_PAINT消息放在应用程序的消息队列中。只有在显示区域的某一部分失效时,窗口才会接受WM_PAINT消息。
Windows内部为每个窗口保存一个「绘图信息结构」,这个结构包含了包围无效区域的最小矩形的坐标以及其它信息,这个矩形就叫做「无效矩形」,有时也称为「无效区域」。如果在窗口消息处理程序处理WM_PAINT消息之前显示区域中的另一个区域变为无效,则Windows计算出一个包围两个区域的新的无效区域(以及一个新的无效矩形),并将这种变化后的信息放在绘制信息结构中。Windows不会将多个WM_PAINT消息都放在消息队列中。
窗口消息处理程序可以通过呼叫InvalidateRect使显示区域内的矩形无效。如果消息队列中已经包含一个WM_PAINT消息,Windows将计算出新的无效矩形。否则,它将一个新的WM_PAINT消息放入消息队列中。在接收到WM_PAINT消息时,窗口消息处理程序可以取得无效矩形的坐标(我们马上就会看到这一点)。通过呼叫GetUpdateRect,可以在任何时候取得这些坐标。
在处理WM_PAINT消息处理期间,窗口消息处理程序在呼叫了BeginPaint之后,整个显示区域即变为有效。程序也可以通过呼叫ValidateRect函数使显示区域内的任意矩形区域变为有效。如果这呼叫具有令整个无效区域变为有效的效果,则目前队列中的任何WM_PAINT消息都将被删除。
现在很明白了,validaterect能使所有的无效区域变为有效,则消息队列中WM_PAINT消息被删除了,当然不会响应了。
所以在重载WM_ONPAINT,它默认会生成一个CPaintDC dc(this);,不要以为这只是一个初始化,就直接把它干掉,这样你的所有整个显示区域就一直无效了.
相关文章推荐
- 0.VC(ui)-InvalidateRect 和validateRect 和wm_paint
- InvalidateRect,ValidateRect,WM_PAINT消息
- InvalidateRect只是增加重绘区域,在下次WM_PAINT的时候才生效
- InvalidateRect只是增加重绘区域,在下次WM_PAINT的时候才生效
- InvalidateRect只是增加重绘区域,在下次WM_PAINT的时候才生效
- WM_PAINT、WM_ERASEBKGND、InvalidateRect、Invalidate之间的关系
- InvalidateRect只是增加重绘区域,在下次WM_PAINT的时候才生效
- WM_PAINT消息详解,使用InvalidateRect或InvalidateRgn函数刻意产生WM_PAINT消息(WIN7里有变化,“调整视觉效果”,将“启用桌面组合”去掉)
- WM_PAINT、WM_ERASEBKGND、InvalidateRect、Invalidate之间的关系转
- WM_PAINT 与 InvalidateRect
- WM_PAINT消息---InvalidateRect不能实时更新问题
- Invalidate() 与 WM_PAINT
- WM_PAINT消息总结
- WM_PAINT介绍及OnPaint()函数的作用原理
- 无效区域 更新区域 重画 WM_PAINT 的关系和机制
- WM_PAINT
- 继承自TWinControl的控件不能在设计期间接受子控件,用代码设置子控件却可以(它的自绘是直接改写PaintWindow虚函数,而不是覆盖Paint函数——对TWinControl.WMPaint又有新解了)
- windows程序设计之InvalidateRect 和 ValidateRect 函数解析
- 深度分析WM_PAINT和WM_ERASEBKGND消息
- windows 编程随笔——输出文本>>WM_PAINT消息|有效矩形和无效矩形