invalidaterect(invalidaterect函数到底如何使用)

本文目录
- invalidaterect函数到底如何使用
- VC中 InvalidateRect,RedrawWindow和UpdateWindow的区别
- InvalidateRect( CRect *)
- windows编程:关于InvalidateRect的第3个参数问题
- 关于invalidaterect的问题
invalidaterect函数到底如何使用
该函数向指定的窗体更新区域添加一个矩形,然后窗口客户区域的这一部分将被重新绘制。
BOOL InvalidateRect(
HWND hWnd, // handle of window with changed update region
CONST RECT *lpRect, // address of rectangle coordinates
BOOL bErase // erase-background flag
);
参数:
hWnd:要更新的客户区所在的窗体的句柄。如果为NULL,则系统将在函数返回前重新绘制所有的窗口, 然后发送WM_ERASEBKGND 和 WM_PAINT 给窗口过程处理函数。
lpRect:无效区域的矩形代表,它是一个结构体指针,存放着矩形的大小。如果为NULL,全部的窗口客户区域将被增加到更新区域中。
bErase:指出无效矩形被标记为有效后,是否重画该区域,重画时用预先定义好的画刷。当指定TRUE时需要重画。
返回值:
函数成功则返回非零值,否则返回零值。
说明:被标记为无效矩形的区域直到WM_PAINT消息被处理完之后才会消失,或者使用ValidateRect(),ValidateRgn()函数来使之有效。当应用程序的消息队列中为空时,并且窗体要更新的区域非空时,系统会发送一个WM_PAINT消息到窗体。
这两个都用于声明客户区无效,当下一个WM_PAINT消息到来时发生重画。
其中InvalidateRect(hwnd, NULL, true);重画时将擦除背景。
InvalidateRect(hwnd, NULL, false);重画时不擦除背景
需要:
Windows NT/2000/XP/Vista: 包含Windows NT 3.1以及之后版本。
Windows 95/98/Me: 包含Windows 95 以及之后版本。
Header: 声明在 Winuser.h中; 包含在Windows.h中。
Library: Use User32.lib.
VC中 InvalidateRect,RedrawWindow和UpdateWindow的区别
InvalidateRect是将客户区标记为无效,并产生WM_PAINT消息,Windows会将WM_PAINT消息放入队列,等待窗口过程的处理,然后操作系统将WM_PAINT当作是低优先级消息,如果后面有其他的动作要处理,则可能会出现空白的区域需要等待一段时间才被刷新。
UpdateWindow则将导致操作系统立即用WM_PAINT调用窗口过程,而不进入队列,使窗口得到立即的刷新。窗口过程完成刷新后立即退出,Windows将控制返回给UpdateWindow之后的语句。
RedrawWindow()则是具有Invalidate()和UpdateWindow()的双特性。声明窗口的状态为无效,并立即更新窗口,立即调用WM_PAINT消息处理。
InvalidateRect只是增加重绘区域,在下次WM_PAINT的时候才生效
InvalidateRect函数中的参数TRUE表示系统会在你画之前用背景色将所选区域覆盖一次,默认背景色为白色,可以通过设置BRUSH来改变背景色。
Invalidate()之后:
...OnPaint()-》OnPrepareDC()-》OnDraw()
所以只是刷新在OnPaint()和OnDraw()函数中的绘图语句。其它地方没有影响。
Invalidate标记一个需要重绘的无效区域,并不意味着调用该函数后就立刻进行重绘。类似于PostMessage(WM_PAINT),需要处理到WM_PAINT消息时才真正重绘。以为您Invalidate之后还有其他的语句正在执行,程序没有机会去处理WM_PAINT消息,但当函数执行完毕后,消息处理才得以进行。
Invalidate只是放一个WM_PAINT消息在队列里,不做别的,所以只有当当前函数返回后,进入消息循环,取出WM_PAINT,才执行PAINT,所以不管Invalidate放哪里,都是最后的。
UpdateWindow只向窗体发送WM_PAINT消息,在发送之前判断GetUpdateRect(hWnd,NULL,TRUE)看有无可绘制的客户区域,如果没有,则不发送WM_PAINT
如果希望立即刷新无效区域,可以在调用InvalidateRect之后调用UpdateWindow,如果客户区的任一部分无效,则 UpdateWindow将导致Windows用WM_PAINT消息调用窗口过程(如果整个客户区有效,则不调用窗口过程)。这一WM_PAINT消息不进入消息队列,直接由WINDOWS调用窗口过程。窗口过程完成刷新以后立刻退出,WINDOWS将控制返回给程序中UpdateWindow调用之后的语句。(windows程序设计第5版 P98)
InvalidateRect( CRect *)
InvalidateRect(&Rect)和Invalidate()两个函数形式和功能差不多,但Invalidate是使得整个窗口无效,形成无效矩形,而InvalidateRect(&Rect)是
使得指定的区域无效。
如果你的OnPaint比较简单时,InvalidateRect(&Rect)和Invalidate()区别不是很大,因为相对重绘量少,所以整个重绘和局部重绘区别不是很明显。当你界面比较复杂时,重绘全部和重绘局部的量就比较明显,InvalidateRect(&Rect)明显效率高于Invalidate()。但是InvalidateRect(&Rect)需要你自己判断哪些区域是无效,而Invalidate()不需要(因为它是全部重绘)。所以当全部重绘的计算量高于判断局部无效的计算量时,更适合使用InvalidateRect(&Rect)。
多个WM_PAINT消息之间通过InvalidateRect使之失效的区域就会被累加起来,然后在一个WM_PAINT消息中一次得到更新,不仅能避免多次重复地更新同一区域,也优化了应用的更新操作。像这种通过InvalidateRect和InvalidateRgn来使窗口区域无效,依赖于系统在合适的时机发送WM_PAINT消息的机 制实际上是一种异步工作方式,也就是说,在无效化窗口区域和发送WM_PAINT消息之间是有延迟的。
windows编程:关于InvalidateRect的第3个参数问题
InvalidateRect()的第三个参数是决定是否给程序发送WM_ERASEBKGND消息,为FALSE的话则不发送该消息。如果想改变背景,可以在该消息的处理过程中对背景做一些处理。拿上面的例子来说就是在switc语句中添加一条:"case WM_ERASEBKGND:。。。//处理过程"。
对于上面的程序为什么仍然会擦除背景是因为:InvalidateRect函数会给系统发送WM_PAINT消息,因此在程序中执行到该函数时则给程序发送WM_PAINT消息,即转到WM_PAINT消息处理里面里,然后由fState){};这条语句就执行了,也就是画了叉,当再点的时候1与1异或又变成0了,所以又把叉给擦了。
说的有点多啊,可能表述的不太清楚。总的来说就是你每点一次左键都会响应一次WM_PAINT消息,而WM_PAINT的处理函数是把整个窗口分成很多个小方框,用一个数组来决定小方框里面是否画叉,如果数组元素为1则画叉,如果为0则不画。每次处理WM_PAINT消息都要对数组进行遍历一次已决定是否画叉。
因此我感觉InvalidateRect的第三个参数是true还是false跟这个程序没啥关系。
关于invalidaterect的问题
先回答你的第二个问题。
scrollWindow并不产生WM_PAINT消息。
程序第一次收到WM_PAINT消息是在你的WinMain函数里,第一次调用UpdateWindow的时候产生的。
接下来,当你的窗口被最小化,或者由于种种原因被遮盖,或者你调用了InvalidateRect这样的函数之后才产生WM_PAINT消息。
具体来说,当你的窗口被遮盖了,这可能是因为你去玩了全屏的3D游戏,把整个桌面都遮盖了,或者是你拿别的窗口把程序的窗口遮盖了等等。
Windows操作系统记录你的窗口的那一部分被遮盖了,叫做“无效部分”。这时候就会产生WM_PAINT消息,WM_PAINT消息的响应代码应当重绘窗口,并通过BeginPaint()和EndPaint()的调用使整个无效部分恢复为有效。
现在回答你的第一个问题。
InvalidateRect的作用就是产生WM_PAINT消息。
WM_COMMAND里面的ValidateRect的作用在于,正常来说,我们在WM_PAINT里面会有BeginPaint()和EndPaint()的调用,这会使得窗口有效。
但是有时候,我们的绘制不是通过BeginPaint()和EndPaint()产生的,这个时候我们却已经绘制了窗口了。这时候可以通过ValidateRect来使窗口有效。
(这时候就不能用BeginPaint()和EndPaint()来使窗口有效了,因为这一对函数只能在处理WM_PAINT消息的时候进行调用。
rect的大小是在WM_SIZE里面确定的。
窗口第一次绘制出来的时候会产生一次WM_SIZE消息。此后每次改变窗口时都会产生这个消息。因此在第一次收到WM_COMMAND消息之前,rect结构体的值就已经在第一次WM_SIZE消息时设置好了。

更多文章:
传奇战域如何升级 快速升级攻略?传奇战域杀戮之地副本该如何打
2026年10月31日 22:40
手机全屏动态壁纸免费下载(哪里可以下载3D视差动态壁纸(还有下载的壁纸是根据屏幕分辨率还是屏幕尺寸))
2025年11月6日 12:15
天天静听和天天动听(我手机是诺基亚6120ci下酷狗和天天动听和天天静听可以下可以吗)
2026年1月15日 10:00
无法激活windows10(Windows10无法激活怎么办)
2025年12月4日 21:00
电脑扬声器100为啥没有声音(电脑扬声器100为什么声音却很小怎么才能把声音调高)
2026年3月6日 22:45
lol加速器有用吗(打lol开加速器有实际的作用吗tgp助手有必要开吗会拖慢网速吗tgp加速有用吗)
2026年5月29日 06:10
pspsfc最完美模拟器下载(PSP用SFC模拟器怎么下载)
2026年9月19日 18:40















