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
我如何将SendMessage
从C
变为D
?
附加信息(来自 cmets):
消息映射已正确完成并已注册消息。这是我尝试过的:
我在 C 类的成员函数中调用 SendMessage(...)
,它不起作用。
当我通过GetTopLevelParent()->SendMessage(...)
执行此操作时,它正在工作。
但在第二种情况中,它击中了侦听器函数3次。你能解释一下为什么吗?
【问题讨论】:
您实际上是在向我们展示一个类层次结构,因为所有类都有一个共同的根,即CWnd
。
最后,我自己添加了(到目前为止)通过 cmets 收集的信息。 @Arjun 请检查您的问题现在描述是否正确,并在必要时进行更正/改进。
【参考方案1】:
由于C
和D
(直接或间接)这两个类都派生自CWnd
,因此它们都应该能够接收通过SendMessage
发送的消息。对我来说,在 D
中实现 接收器部分 时,您很可能遗漏了一些东西。
确实,您拥有的不是两个层次结构。由于公共根类是CWnd
,它是一个层次结构:
您必须将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->SendMessage(some_msg_id, p1, p2);
,因为在 C++ 中,每个成员函数都有一个隐式的 this
参数(也就是说 - 如果适用的话 - 也隐式地用于进一步的调用)。成员函数中this
的值是当前调用该函数的对象。因此,如果您有一个 C
类的对象 cObj
并调用 cObj.something
,则调用成员函数 C::something
,其中隐式参数 this
为该调用的 cObj
。如果您从一个成员函数内进行调用,C++ 会检查两个命名空间以解析该调用:
在自己的成员函数的情况下,this
被隐式使用,因此您为类C
的对象调用SendMessage
。您要做的是调用类D
的对象,因此您需要获取指向某个dObj
的指针。
当您调用GetTopLevelParent()->SendMessage(...)
时,您将消息提供给更通用的消息分发机制,该机制将其广播到子窗口。这就是您在目标对象中多次看到该消息的原因。但这只是因为D
-class 对象是与C
-class 对象相同的***父对象的子对象。
【讨论】:
以上是关于SendMessage 发送的消息在其他类层次结构中未收到的主要内容,如果未能解决你的问题,请参考以下文章
消息与函数,postmessage与sendmessage,该怎么解决
使用findwindow找到隐藏窗口使用sendmessage发送wm_close消息,无法关闭。