I understand, from MSDN, how windows handles WM_PAINT messages sent to a particular window.

One thing MSDN doesn't seem to document is the actual process by which the window manager decides which windows should receive WM_PAINT messages, and in what order.

As I understand things (from reading Raymond Chen and MSDN) there are no invalid regions associated with child windows - when child windows are invalidated the corresponding area on the parent window gets invalidated.

Its the WM_PAINT generation that confuses me... and the exact point (especially wrt multithreading) that a windows invalid region gets marked as valid - when child windows are involved it gets particularly interesting. How does GetMessage decide which of the set of windows (parents + child windows that intersect the invalid region) get WM_PAINT messages, and in what order? and how does that change in the face of WS_CLIPSIBLINGS, WS_CLIPCHILDREN, WS_EX_COMPOSITED, WS_EX_TRANSPARENT and so on? And what happens if another thread invalidates part of the top level window halfway through this process?

And then, On Windows V6.0+, how does the DWM hook into this process?

This is a sample C program demonstrating the glitching that occurs when using WS_EX_COMPOSITED :-

one thing I'd like to know is why you think WS_EX_COMPOSITED has no effect when DWM composition is active.
–
David HeffernanApr 21 '11 at 11:13

2

Hmm, I suspect it's not documented because it's not supposed to be relevant. They don't want to commit to sending WM_PAINT messages in any particular order, and it's an extremely unusual case that an application would care what order they were sent in. The implementation should be transparent. Are you asking purely out of curiosity, or are you trying to solve some particular problem? And as far as DWM, it doesn't hook into the process at all. Each top-level window is automatically layered and redirected to an off-screen buffer. This buffer is then blitted to the screen.
–
Cody GrayApr 21 '11 at 11:13

1

Agreed. This is done by the window manager, a particularly undocumented chunk of code. There's plenty of anecdotal evidence of how it works but that's not what you are asking for. Nail this question to the wall with a specific issue you are trying to solve so we don't have to write a book about undocumented code.
–
Hans PassantApr 21 '11 at 11:47

Well, in answer to both David and Hans, I am wondering my my test app, using WS_EX_COMPOSITED, flickers when resized, with DWM enabled.
–
Chris BeckeApr 21 '11 at 12:40

1

@Chris I do believe you. It's just that it solved my problems. Clearly we are doing different things elsewhere in our code.
–
David HeffernanMay 3 '11 at 13:00

1 Answer
1

The traditional model was that nothing was remembered (because memory was expensive), hence whenever a window was covered, the contents was forgotten, and it was redrawn in response to WM_PAINT.

But you knew this.

From the application point of view, the main change to this model the DWM makes is not to painting but to invalidation, i.e. causing painting to be required. Regions are not (necessarily) invalidated when covered by other windows, since the DWM remembers what the window looks like, and so doesn't need to ask the application "Remind me what you wanted to display there again?".

If you invalidate a region yourself either explicitly or implicitly (via SetWindowText for example) then it will still get WM_PAINT.

When painting the parent, children may or may not be clipped depending on whether that is set. I believe painting is done back-to-front, to allow child controls to (for example) draw 3D borders outside their own rectangle, as in Microsoft Word 6, if you remember that far back!

As far as I know this is not documented, and since you quoted Raymond Chen, you will know he would caution you against relying on the order of WM_PAINT messages.