Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Order of Parent / Child WM_PAINT messages

330 views
Skip to first unread message

Timothy Dean

unread,
Nov 27, 2007, 8:44:58 PM11/27/07
to
I have a parent window (CFormView) that contains child controls (such as
CEdit, CButton, etc...). I need to do some drawing in the parent window
after all the child controls are painted. Currently, the parent receives
WM_PAINT first, and then all of the child controls are painted over what I
just drew in the parent window. How do I know when all of the child
controls are done painting so I can then draw in the parent? Changing z
order of the parent doesn't seem to help. Thanks.

Timothy Dean


Joseph M. Newcomer

unread,
Nov 28, 2007, 1:28:57 AM11/28/07
to
They happen in some order. There is no reason to assume any order dependency exists.

You should create the parent with the WS_CLIPCHILDREN style.

It is rare to ever draw on a CFormView directly.
joe

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Tom Serface

unread,
Nov 28, 2007, 10:58:13 AM11/28/07
to
Depending on what you "write" onto the view you may want to consider just
doing a custom control or using a control (like a CStatic) to contain your
custom stuff. That way it is easier to manage. You can, of course, do
things like write on the background or change background color, etc. pretty
easily, but if you are extending a control I think it should be part of the
control and not the view.

Tom

"Timothy Dean" <tim....@mobiledataforce.com> wrote in message
news:uQh1JBWM...@TK2MSFTNGP04.phx.gbl...

Timothy Dean

unread,
Nov 28, 2007, 5:58:36 PM11/28/07
to
This is drawing that I have to do on top of other controls to "decorate"
them. The controls are actually contained in another CWnd that is contained
inside the form view. Once all of the child windows contained in the form
are painted, I then need to do drawing on top of the controls in a type of
layered system (similar to AutoCAD). Whether or not I draw to the view
isn't the issue. I could contain everthing in another CWnd, but I would
still have the same problem. The parent CWnd or CFormView receives the
paint first, and then all of the child windows receive the paint message.
How would I draw something to the parent window that will overlap any child
controls? If I could somehow get the paint message sent to the parent last,
everything would be ok. Is there a way to change the z order that would
control the order? Would I be better off creating another CWnd that would
overlap all of the other controls, but would be a sibling instead of a
parent to all the other controls? Thanks.

Timothy Dean

"Tom Serface" <tom.n...@camaswood.com> wrote in message
news:262C18CA-05A8-4FA7...@microsoft.com...

Tom Serface

unread,
Nov 28, 2007, 7:34:10 PM11/28/07
to
I've never tried to do what you're doing, but if I were to do it I'd
probably still try to use something like a CStatic (transparent) then draw
what I needed on the control. You may find Ali's article to be interesting:

http://www.codeproject.com/staticctrl/TransparentStaticCtrl.asp

Tom

"Timothy Dean" <tim....@mobiledataforce.com> wrote in message

news:e74b3IhM...@TK2MSFTNGP02.phx.gbl...

Joseph M. Newcomer

unread,
Nov 28, 2007, 9:34:59 PM11/28/07
to
Bad idea; you cannot draw onto other controls; only the other controls OnPaint handlers
can draw on the other controls. There is no possible way you could know when to decorate
a control. There is no support for layering as you describe.

You would have to subclass the controls, intercept the OnPaint notifications, and handle
them there, which is nontrivial in and of itself, but take it that without doing this it
is IMPOSSIBLE to know when a control redraws itself. Or you could use an in-process hook
function to accomplish this. But you can safely assume that (a) you have no control over
drawing order and (b) no idea when to draw anything anywhere under any conditions, unless
you know when the WM_PAINT message comes in for that control! While it may appear that
there is an order to the messages, there are lots of ways this order can change, so you
can't rely on it. Z-order is irrelevant because the parent dialog is implicitly below
every other control and this cannot be changed.

If you place some other control on top of the control, it would have to be a transparent,
non-responsive, CStatic, and you would have to invalidate it whenever you intercepted a
WM_PAINT for the control it covers...and that's just a guess on my part that it could be
made to work at all. And I'm not sure that would work, anyway. Windows just has too many
assumptions built in that you are trying to violate all over the place, and therefore you
are fighting the basic design of the system.

Why don't the controls decorate themselves? You are trying to accomplish something that
is not really supported by the fundamental operating system, and most attempts to achieve
what you want that do not involve actually subclassing the controls themselves, and in the
case of WM_PAINT this is a really, really dangerous thing to do, is likely going to be
doomed.
joe

Timothy Dean

unread,
Nov 29, 2007, 1:20:24 PM11/29/07
to
Thanks. That is helpful to know. The controls I am decorating are already
custom controls. The controls actually do decorate themselves, but they
can't draw the decorations to their own window. The reason is that the
decorations actually exceed the boundry of each controls window. The
decorations for a single control overlap itself as well as other adjacent
controls. It seems like the answer is to create another window drawn over
the entire page of controls. This window would be a sibling to the controls
and drawn last.

Timothy Dean


"Joseph M. Newcomer" <newc...@flounder.com> wrote in message
news:9t8sk39qhvo8kuptv...@4ax.com...

Joseph M. Newcomer

unread,
Nov 29, 2007, 7:28:34 PM11/29/07
to
Well, up to but not including Vista, you actually can do this, because of a design error
in Windows: most controls use CS_PARENTDC, which means the DC has a clipping region
equivalent to the parent clipping region. But they fixed this design defect in Vista.

There are a couple ways to handle this. For example, you could use a "buddy" window, a
CStatic that was of the desired size and which was the immediate predecessor in the
Z-order. So the custom control would then get the previous control in the Z-order, and
SendMessage a user-defined message to it. This control would simply draw itself. If the
dialog has WS_CLIPSIBLINGS, then it will not overwrite its sibling control. If I wanted
to do this, that's the approach I'd take. Note that if the immediate sibling is NOT one
of your magical decoration CStatics, then the message will be ignored (I would not use
other than a RegisteredWindowMessage message for this). Or, you could have a "master"
CStatic that covered the entire dialog, and you would SendMessage the handle or CWnd* of
your current control. From this handle or CWnd*, you can GetWindowRect, ScreenToClient,
expand the resulting rectangle by the size of the decoration, Invalidate that area, and
just let that window redraw. It would query each custom control by doing a SendMessage of
a RegisteredWindowMessage, saying "please tell me about your decorations" and the LRESULT
would either be NULL ("no decorations, or I'm not one of your custom windows") or a
pointer to some useful information that tells it what decorations to add. Both of these
are substantially easier than most other approaches I can think of.
joe

Joseph M. Newcomer

unread,
Nov 30, 2007, 1:57:04 AM11/30/07
to
Alternatively, the "buddy", in its WM_PAINT handler, could SendMessage to the control "on
its right" to ask it what decorations need to be provided.
joe
0 new messages