From: Joseph M. Newcomer on
No. You would simply send it to the parent. The parent, if it receives the message,
either processes it or sends it to *it's* parent, and so on.

Alternatively, you would write a loop which went upwards until it hit NULL then send the
message to the topmost window in the hierarchy. See my other message; this window would
send it back down to all descendants.

Note that I usually do this by creating a superclass which handles the message and all I
would do in a subclass that cared about the message is handle the message in that
subclass.

See my essay on subclassing dialogs (and property pages and CFormViews) on my MVP Tips
site.

The code you show is absolutely horrendous, and should never, ever, be written!
joe

On Thu, 3 Dec 2009 08:51:02 -0800, Cameron_C <CameronC(a)discussions.microsoft.com> wrote:

>Thanks,
>And if it is nested, then I guess I would expand to something like:
> ASSERT(GetParent() != NULL);
> ASSERT(GetParent()->GetParent() != NULL);
> ASSERT(GetParent()->GetParent()->GetParent() != NULL);
> ASSERT(GetParent()->GetParent()->GetParent()->GetParent() != NULL);
> ASSERT(GetParent()->GetParent()->GetParent()->GetParent()->GetParent() !=
>NULL);
>
>GetParent()->GetParent()->GetParent()->GetParent()->GetParent()->SendMessage(WM_.......);
>
>It starts to get interesting....
>
>"AliR" wrote:
>
>> I'm assuming that the parent of your TabDialog is the CTabCtrl, and the
>> button is on the parent window of the CTabCtrl.
>>
>> If that's the case and I was doing this, I would do this:
>> ASSERT(GetParent() != NULL);
>> ASSERT(GetParent()->GetParent() != NULL);
>> GetParent()->GetParent()->SendMessage(WM_.......);
>>
>> AliR.
>>
>> "Cameron_C" <CameronC(a)discussions.microsoft.com> wrote in message
>> news:1735E30C-9386-46E1-AFAA-DC5EBD7730A2(a)microsoft.com...
>> > Hello guys, I have one more question relating to nexted CTabCtrls.
>> > I got some great information from Joe, and I have been able to next the
>> > CTabCtrls although I believe I hurt myself getting it to work.
>> >
>> > I am now in a position where I would like to change the text on a button
>> > on
>> > the main dialog from within the nested CTabCtrl dialog.
>> > I see two options here (maybe there are others).
>> > First, I could pass a pointer to the button control all the way down the
>> > nested control structures, as I am creating the nested controls. This
>> > would
>> > be explicit, so easy to follow for future maintenance, but it seems to be
>> > a
>> > bit "cludgy".
>> >
>> > The second choice would be to send a message to the main dialog window to
>> > change the text. In this case, could I just post the message to the
>> > parent,
>> > and if the parent does not handle the message it should be passed up to
>> > its
>> > parent, and so on.
>> > This would appear to be a "cleaner" solution.
>> > I guess I am looking for advice again. Which would be a better approach?
>> > I am leaning towards the second approach.
>> >
>> > Thanks guys.
>>
>>
>> .
>>
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Goran on
On Dec 3, 6:09 pm, Joseph M. Newcomer <newco...(a)flounder.com> wrote:
> >The second choice would be to send a message to the main dialog window to
> >change the text. In this case, could I just post the message to the parent,
> >and if the parent does not handle the message it should be passed up to its
> >parent, and so on.
>
> ****
> That's what I would do.  So any window in between that wanted to change text could do so
> also.  I also have used the trick of letting the message flow upward transparently, then
> from the topmost window (the one that contains the topmost CTabCtrl) do a
> "SendToAllDescendants" and let someone who cares worry about it.
>
> Third solution is to treat the topmost window as a "document" so you send a message to
> change its state, and it does a SendMessageToDescendants to say "something changed"
> (UpdateAllViews equivalent) and a window that wants something sends it a message that says
> "I care about..." and gets a pointer/value in return (e.g., for a BOOL I'd return a value,
> but for a string, I'd return a pointer)

To expand on this, depending on how complicated this can get, it could
also beneficial to just roll your own parent-child relationship with
some updating mechanism. Usage of messages is OK, but:

1. I got burned with property sheets, where it happened that target
page wasn't created (didn't have a HWND) when I wanted to get to it.
2. WM_XXX approach is less type-safe, because with SendMessage you are
contrained to BOOL return value and LPARAM, WPARAM pair, so more
diligence is needed.

Instead, imagine that you have:

struct UpdateMechanics /*bad name, I know*/
{
UpdateMechanics(UpdateMechanics* pParent);
UpdateMechanics* GetUMParent();

virtual void OnUpdate(HintType lHint, HintObject* pHint) = 0;
// Inspired by UpdateAllViews. Modifiable at will ;-).
};

With this, you derive your tabs from whatever MFC type you have and
UpdateMechanics, e.g:

class CMyTab: public CTabCtrl, public UpdateMechanics{};

And now, when you want to modify your button (or whatever update you
might want to have), you go e.g.:

void CMyTab::SomethingChanged()
{
// ...
UpdateMechanics* pParent = GetUMParent();
if (pParent)
pParent->OnUpdate(HintSomethingChanged, &ChangedObject);
// ...
}

Of course, you override OnUpdate in various classes and react to
"change hints", which you can define as you want (particularly, with
of compilation type-checks of your choosing).

Note that all this is simply a very primitive and not a very good
implementation of ideas behind model-view-controller (http://
www.google.be/search?q=model-view-controller) pattern. We all might
want to read up on that ;-).

Goran.
From: Joseph M. Newcomer on
See below...
On Fri, 4 Dec 2009 01:31:18 -0800 (PST), Goran <goran.pusic(a)gmail.com> wrote:

>On Dec 3, 6:09�pm, Joseph M. Newcomer <newco...(a)flounder.com> wrote:
>> >The second choice would be to send a message to the main dialog window to
>> >change the text. In this case, could I just post the message to the parent,
>> >and if the parent does not handle the message it should be passed up to its
>> >parent, and so on.
>>
>> ****
>> That's what I would do. �So any window in between that wanted to change text could do so
>> also. �I also have used the trick of letting the message flow upward transparently, then
>> from the topmost window (the one that contains the topmost CTabCtrl) do a
>> "SendToAllDescendants" and let someone who cares worry about it.
>>
>> Third solution is to treat the topmost window as a "document" so you send a message to
>> change its state, and it does a SendMessageToDescendants to say "something changed"
>> (UpdateAllViews equivalent) and a window that wants something sends it a message that says
>> "I care about..." and gets a pointer/value in return (e.g., for a BOOL I'd return a value,
>> but for a string, I'd return a pointer)
>
>To expand on this, depending on how complicated this can get, it could
>also beneficial to just roll your own parent-child relationship with
>some updating mechanism. Usage of messages is OK, but:
>
>1. I got burned with property sheets, where it happened that target
>page wasn't created (didn't have a HWND) when I wanted to get to it.
****
What solves this is using the property sheet itself as the "document". That way, you
never, ever have to care whether a page is defined or not. Each page is responsible, in
its OnSetActive handler, for setting up whatever it cares about (which may involve
obtaining values from the "document", that is, the property sheet), and upon its
OnKillActive handler, making sure that the "document" is consistent with its controls. The
myth that you want to always use SendMessage across peers now goes away, because you
never, ever have to care if a page exists.
****
>2. WM_XXX approach is less type-safe, because with SendMessage you are
>contrained to BOOL return value and LPARAM, WPARAM pair, so more
>diligence is needed.
****
SendMessage is not constrained to BOOL; in fact, the new spec is INT_PTR as the return
type from a dialog handler.

The type safety issue is indeed a concern, but I've found that careful documentation
usually solves that problem. But if you don't use messages, you end up with a mess of
interdependencies, and I've found that is far worse to deal with.
****
>
>Instead, imagine that you have:
>
>struct UpdateMechanics /*bad name, I know*/
>{
> UpdateMechanics(UpdateMechanics* pParent);
> UpdateMechanics* GetUMParent();
>
> virtual void OnUpdate(HintType lHint, HintObject* pHint) = 0;
> // Inspired by UpdateAllViews. Modifiable at will ;-).
>};
>
>With this, you derive your tabs from whatever MFC type you have and
>UpdateMechanics, e.g:
>
>class CMyTab: public CTabCtrl, public UpdateMechanics{};
>
>And now, when you want to modify your button (or whatever update you
>might want to have), you go e.g.:
>
>void CMyTab::SomethingChanged()
>{
> // ...
> UpdateMechanics* pParent = GetUMParent();
> if (pParent)
> pParent->OnUpdate(HintSomethingChanged, &ChangedObject);
> // ...
>}
>
>Of course, you override OnUpdate in various classes and react to
>"change hints", which you can define as you want (particularly, with
>of compilation type-checks of your choosing).
****
This is the technique used to handle multiple views from a single document, and I just
generalized it to multiple property pages from a single property sheet. The solution is
completely symmetric.
joe
****
>
>Note that all this is simply a very primitive and not a very good
>implementation of ideas behind model-view-controller (http://
>www.google.be/search?q=model-view-controller) pattern. We all might
>want to read up on that ;-).
>
>Goran.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm