SendMessage 发送的消息在其他类层次结构中未收到

Posted

技术标签:

【中文标题】SendMessage 发送的消息在其他类层次结构中未收到【英文标题】:Message sent by SendMessage is not recieved in other class hierarchy 【发布时间】:2020-05-12 07:12:17 【问题描述】:

我有两个类层次结构,如下所示:

    A 类扩展 CWnd B 扩展 A C 扩展 B. D 类扩展 CWnd E 扩展 D

我如何将SendMessageC 变为D

附加信息(来自 cmets):

消息映射已正确完成并已注册消息。这是我尝试过的:

    我在 C 类的成员函数中调用 SendMessage(...),它不起作用。

    当我通过GetTopLevelParent()->SendMessage(...) 执行此操作时,它正在工作。

但在第二种情况中,它击中了侦听器函数3次。你能解释一下为什么吗?

【问题讨论】:

您实际上是在向我们展示一个类层次结构,因为所有类都有一个共同的根,即CWnd 最后,我自己添加了(到目前为止)通过 cmets 收集的信息。 @Arjun 请检查您的问题现在描述是否正确,并在必要时进行更正/改进。 【参考方案1】:

由于CD(直接或间接)这两个类都派生自CWnd,因此它们都应该能够接收通过SendMessage 发送的消息。对我来说,在 D 中实现 接收器部分 时,您很可能遗漏了一些东西。

确实,您拥有的不是两个层次结构。由于公共根类是CWnd,它是一个层次结构

CWnd(公共根类) A(扩展 CWnd) B(扩展 A) C(扩展 B) D(扩展 CWnd) E(扩展 D)

您必须将user-defined handler 添加到D 的消息映射中。

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

阅读此处了解更多信息

User-Defined Handlers | Microsoft Docs Message Maps (MFC) | Microsoft Docs

发送到不同的CWnd对象

要发送到某个CWnd 派生类的对象,调用SendMessage on it 就足够了。这也是可能的,而不必“从CWmd 作为发件人派生”,例如:

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

底层基础设施

MFC 提供了对基本 Windows 消息传输技术的轻松访问。[1] 这种消息传输技术不仅用于传递信息,还用于管理控制流。其主要目标是为事件驱动的应用程序提供基础设施。在这里阅读更多:

Messages and Message Queues - Win32 apps | Microsoft Docs Window Procedures - Win32 apps | Microsoft Docs

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

【讨论】:

消息映射已正确完成,消息已注册。我正在尝试在 C 类中编写 SendMessage(Message Id, parameters) 所以它不起作用,但是当我像 CWnd* p = GetTopLeveParent();然后 p->SendMessage 它正在工作 但是它击中了监听函数 3 次不知道为什么?【参考方案2】:

我从你的 cmets 中读到了 1

消息映射已正确完成并已注册消息。我正在尝试在 C 类中编写 SendMessage(Message Id, parameters) 所以它不起作用,但是当我像 CWnd* p = GetTopLeveParent();然后 p->SendMessage 它正在工作

2

但是它击中了监听函数 3 次不知道为什么?

...您只是在C 的某个成员函数中调用SendMessage

void C::something() 

    SendMessage(some_msg_id, p1, p2);

但是在这里你实际上是在调用this-&gt;SendMessage(some_msg_id, p1, p2);,因为在 C++ 中,每个成员函数都有一个隐式的 this 参数(也就是说 - 如果适用的话 - 也隐式地用于进一步的调用)。成员函数中this 的值是当前调用该函数的对象。因此,如果您有一个 C 类的对象 cObj 并调用 cObj.something,则调用成员函数 C::something,其中隐式参数 this 为该调用的 cObj。如果您从一个成员函数进行调用,C++ 会检查两个命名空间以解析该调用:

全局函数 拥有(和继承的)成员函数

在自己的成员函数的情况下,this 被隐式使用,因此您为类C 的对象调用SendMessage。您要做的是调用类D 的对象,因此您需要获取指向某个dObj 的指针。

当您调用GetTopLevelParent()-&gt;SendMessage(...) 时,您将消息提供给更通用的消息分发机制,该机制将其广播到子窗口。这就是您在目标对象中多次看到该消息的原因。但这只是因为D-class 对象是与C-class 对象相同的***父对象的子对象。

【讨论】:

以上是关于SendMessage 发送的消息在其他类层次结构中未收到的主要内容,如果未能解决你的问题,请参考以下文章

sendmessage这个发送消息的函数如何发送字符串

消息与函数,postmessage与sendmessage,该怎么解决

SendMessage和PostMessage的异同

使用findwindow找到隐藏窗口使用sendmessage发送wm_close消息,无法关闭。

c# 调用 win32 API的 SendMessage 函数 ,里面的属性用法?

如何用 sendmessage 发送键盘按键消息