From: Joseph M. Newcomer on 3 Dec 2009 13:09 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 4 Dec 2009 04:31 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 4 Dec 2009 14:38 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
First
|
Prev
|
Pages: 1 2 Prev: How to read an XML file in Visual C++ 6 Next: Client Server and Throttling |