Valid and Invalid Rectangles

Although a window procedure should be prepared to update the entire client area whenever it receives a WM_PAINT message, it often needs to update only a smaller rectangular area. This is most obvious when part of the client area is overlaid by a dialog box. Repainting is required only for the rectangular area uncovered when the dialog box is removed.

That rectangular area is known as an ”invalid rectangle.“ The presence of an invalid rectangle in a client area is what prompts Windows to place a WM_PAINT message in the application's message queue. Your window procedure receives a WM_PAINT message only if part of your client area is invalid.

Windows internally maintains a ”paint information structure“ for each window. This structure contains (among other information) the coordinates of the invalid rectangle. If another rectangular area of the client area becomes invalid before the window procedure processes the WM_PAINT message, Windows calculates a new invalid rectangle that encompasses both areas and stores this updated information in the paint information structure. Windows does not place multiple WM_PAINT messages in the message queue.

A window procedure can invalidate a rectangle in its own client area by calling InvalidateRect. If the message queue already contains a WM_PAINT message, Windows calculates a new invalid rectangle. Otherwise, it places a WM_PAINT message in the message queue. A window procedure can obtain the coordinates of the invalid rectangle when it receives a WM_PAINT message (as we'll see shortly). It can also obtain these coordinates at any other time by calling GetUpdateRect.

After the window procedure calls EndPaint during the WM_PAINT message, the entire client area is validated. A program can also validate any rectangular region in the client area by calling the ValidateRect function. If this call has the effect of validating the entire invalid area, then any WM_PAINT message currently in the queue is deleted.