-2

I have two class hierarchies as shown below:

  1. Class A extends CWnd
    • B extends A
    • C extends B.
  2. Class D extends CWnd
    • E extends D

How can I SendMessage from C to D?

Additional information (from comments):

Message Mapping is done correctly and message is registered. Here is what I tried:

  1. I call SendMessage(...) in a member function of class C, it's not working.

  2. When I am doing it by GetTopLevelParent()->SendMessage(...) it is working.

But in the second case, it's hitting the listener function 3 times. Can you explain why?

Wolf
  • 9,679
  • 7
  • 62
  • 108
Arjun
  • 1
  • You are actually showing us **one class hierarchy** since all classes have a common root which is `CWnd`. – Wolf May 12 '20 at 15:03
  • Finally, I myself added the information that has been gathered (so far) via comments. @Arjun please check if your problem is now described correctly and make corrections / improvements if necessary. – Wolf May 12 '20 at 15:15

2 Answers2

0

Since both classes, C and D (directly or indirectly) derive from CWnd, both should be able to receive messages sent via SendMessage. To me it's high likely that you missed something when implementing the receiver part in D.

Indeed it's not two hierarchies you have. Since the common root class is CWnd, it's one hierarchy:

  • CWnd (common root class)
    • A (extends CWnd)
      • B (extends A)
        • C (extends B)
    • D (extends CWnd)
      • E (extends D)

You have to add a user-defined handler to the message map of D.

BEGIN_MESSAGE_MAP(CMyDoc, CDocument)
   ON_MESSAGE( <message>, <memberFxn> )
   // ...
END_MESSAGE_MAP()

Read here for further information

Send to different CWnd object

As to send to an object that is of some CWnd-derived class, it's enough to call SendMessage on it. This is also possible without having to be "derived from CWmd as the sender", for example like this:

LRESULT send_to_D(D* d) {
   return d->SendMessage(WM_APP+1, 0, 0);
}

Underlying infrastructure

MFC provide easy access to the basic Windows message transfer technology.[1] This message transfer technology is not only for passing informations but also for managing control flow. Its main goal is to provide the infrastructure for event driven applications. Read more here:


[1] Relationship Between a C++ Window Object and an HWND | Microsoft Docs

Wolf
  • 9,679
  • 7
  • 62
  • 108
  • Message Mapping is done correctly and message is registered. What I am trying is in class C I am writing SendMessage(Message Id, parameters) so its not working, but when I am doing like CWnd* p = GetTopLeveParent(); then p->SendMessage it is working – Arjun May 12 '20 at 07:49
  • But its hitting the listener function 3 times not sure why? – Arjun May 12 '20 at 07:53
0

I read from your comments 1

Message Mapping is done correctly and message is registered. What I am trying is in class C I am writing SendMessage(Message Id, parameters) so its not working, but when I am doing like CWnd* p = GetTopLeveParent(); then p->SendMessage it is working

and 2

But its hitting the listener function 3 times not sure why?

... that you are just calling SendMessage within some member function of C:

void C::something() 
{
    SendMessage(some_msg_id, p1, p2);
}

But here you are actually calling this->SendMessage(some_msg_id, p1, p2); because in C++, each member function has an implicit this parameter (that is - if applicable - also implicitly used for further calls). The value of this within a member function is the object for which the function is currently called. So if you have an object cObj of class C and you call cObj.something, you invoke the member function C::something with the implicit parameter this being cObj for that call. If you do a call from within a member function, C++ checks two namespaces for resolving that call:

  • global functions
  • own (and inherited) member functions

In the case of own member functions, this is used implicitly, so you call SendMessage for an object of class C. What you want to do is calling an object of class D, so you need to get a pointer to some dObj.

When you call GetTopLevelParent()->SendMessage(...), you give the message to a more general message distribution mechanism that broadcasts it to child windows. That's why you see the message more than once in your target object. But this is only because the D-class object is a child of the same top level parent as the C-class object.

Wolf
  • 9,679
  • 7
  • 62
  • 108