更新时间:2015-12-14 13:44:12浏览次数:1+次
BOOL GetUpdateRect(HWND hWnd,LPRECT lpRect,BOOL bErase);
第一个参数时窗口的句柄,指示是要获取哪个窗口的无效矩形信息。第二个参数是接收得到的无效矩形的信息的RECT结构体指针。如果有多个无效区域,那么这个结构体就存储了包含多个无效矩形的最小矩形。如果这个参数设置为NULL,那么函数返回值为非零,表示存在无效矩形,否则返回0表示不存在无效矩形。这个特点就可以用来判断无效矩形是否存在。这个就是判断是否是因为无效矩形导致的WM_PAINT消息。因为只要存在无效矩形,就会产生WM_PAINT消息。
这个窗口同时有两个小的分开的无效矩形(示意图)
合并之后的包含两个小无效矩形的最小无效矩形即最外面的矩形
在《WM_PAINT消息处理中的客户区重绘消息死循环问题详细分析和代码验证》一文中,我详细解释了WM_PAINT和无效矩形的关系,无效矩形存在一定要产生WM_PAINT消息。然而WM_PAINT的产生并不会全部因为无效矩形,因为你可以使用SendMessage或者PostMessage函数发送这个消息。此时并不存在无效矩形,因此没有必要对无效矩形进行重绘。通过这个函数的判断,就可以进行重绘的优化。RECT rect;
GetUpdateRect(hWnd,&rect,FALSE);
第三个参数是否要擦除无效矩形区域的背景,如果为TRUE,且确实存在无效矩形,那么就会发送一个WM_ERASEBKGND擦除背景的消息去处理擦除背景。如果为FALSE表示不擦除无效区域的背景。这里指的不是整个客户区的背景,只是无效区域底下的背景。#include "windows.h"
#include <tchar.h>
// - 项目是Unicode字符集
LRESULT CALLBACK WinProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect,rect1;
int i;
TCHAR Msg[100]=_T("");
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hwnd,&ps);//会清除无效矩形
EndPaint(hwnd,&ps);
return 0;
case WM_LBUTTONDOWN:
rect.left=0;
rect.top=0;
rect.right=100;
rect.bottom=100;
InvalidateRect(hwnd,&rect,FALSE);// - 设置无效矩形的大小
if(GetUpdateRect(hwnd,NULL,FALSE))// - 判断无效矩形是否存在
{
GetUpdateRect(hwnd,&rect1,TRUE);//-获取无效矩形的大小
wsprintf(Msg,_T("无效矩形区域:x=%d,y=%d,宽=%d,高=%d"),rect1.left,rect1.top,rect1.right,rect1.bottom);
MessageBox(hwnd,Msg,_T("C++技术网提示"),MB_OK);
}
else
{
MessageBox(hwnd,_T("没有无效区域"),_T("提示"),MB_OK);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrev,LPSTR lpCmd,int iShow)
{
TCHAR ClassName[] = _T("MyClass");
TCHAR title1[] = _T("C++技术网http://www.cjjjs.com");
WNDCLASS wndClass;
wndClass.cbClsExtra=0;
wndClass.cbWndExtra=0;
wndClass.hbrBackground= (HBRUSH)GetStockObject(GRAY_BRUSH);
wndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wndClass.hInstance = hInstance;
wndClass.lpfnWndProc = WinProc;
wndClass.lpszClassName = ClassName;
wndClass.lpszMenuName=NULL;
wndClass.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClass(&wndClass))
{
return 0;
}
HWND hwnd = CreateWindow(ClassName,title1,WS_OVERLAPPEDWINDOW,0,0,440,400,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,SW_SHOWNORMAL);
MSG msg;
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}