使用MFC的CStatic中的事件并将它们传递给父级
我正在构建 MFC 应用程序,其中有 CDialog 以及从 CStatic 派生的子控件。
我想接收 CStatic 控件的鼠标事件,因此我将其设置为 true。现在我可以直接在 MyStatic
中通过消息映射接收消息事件:
class CMyStatic : public CStatic
{
afx_msg void OnLButtonDown(UINT nFlags, CPoint point); // Gets invoked
DECLARE_MESSAGE_MAP()
}
问题是,从现在开始,当鼠标位于 MyStatic
子级上时,父级 CDialog 不再接收鼠标事件。我可以从 MyStatic
手动发送它们,但是有什么方法可以让它们自动通过吗?并且仍然能够使用消息映射在 MyStatic
上接收它们?
I am building MFC application where there is CDialog with child control derived from CStatic on it.
I want to receive mouse events for CStatic control so I set "Notify"
for it to true. Now I am able to receive message events through message map directly in MyStatic
:
class CMyStatic : public CStatic
{
afx_msg void OnLButtonDown(UINT nFlags, CPoint point); // Gets invoked
DECLARE_MESSAGE_MAP()
}
The problem is that from now the parent CDialog is not receiving mouse events when mouse is over MyStatic
child. I can send them from MyStatic
manually but is there any way to let them go through automatically? And still be able to receive them also on MyStatic
using message maps?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不,你误会了。 SS_NOTIFY 不会导致 CStatic 接收消息,它会导致 CStatic 将消息中继回父级。所以“现在我可以直接在 MyStatic 中通过消息映射接收消息事件”是基于一个错误的前提。
这是很重要的一点,因为控件只能接收其自身的消息,而不能接收其子级的消息,除非这些子级通过转发消息或执行其他技巧(全局挂钩,.. .);但这些情况是例外,“正常”方式是每个窗口自己接收消息。
这样就回答了您的问题:不,没有办法让父级(您的 CDialog)和子级(您的 CStatic)都接收鼠标事件,而无需“手动”执行此操作或参与繁琐的消息路由黑客攻击。因此,在您的情况下,您需要做的是 GetParent()->SendMessage(WM_LBUTTONDOWN, ...) 等,手动重新创建 WPARAM 和 LPARAM 值;或者直接在 CDialog 上调用 OnLButtonDown:GetParent()->OnLButtonDown(...)。您必须考虑将什么鼠标坐标传递回 CDialog,但您可能需要将它们转换为 CDialog 的客户端坐标。
No, you're misunderstanding. SS_NOTIFY does not cause your CStatic to receive messages, it causes the CStatic to relay messages back to the parent. So "Now I am able to receive message events through message map directly in MyStatic" is based on a false premise.
This is an important point to make because a control can only receive messages for itself, not for its children, unless those children 'play along' by relaying messages or by doing other tricks (global hooking, ...) ; but those cases are the exception, the 'normal' way is that each window receives messages for itself.
So that answers your question: no, there is no way to let both a parent (your CDialog) and a child (your CStatic) receive mouse events without doing so 'manually' or getting involved in tedious message routing hacks. So in your case, what you need to do is GetParent()->SendMessage(WM_LBUTTONDOWN, ...) etc, manually recreating the WPARAM and LPARAM values; or calling OnLButtonDown directly on the CDialog: GetParent()->OnLButtonDown(...). You'll have to think about what mouse coordinates you pass back to CDialog though, you may need to translate them to the CDialog's client coordinates.
如果调用基本 OnLButtonDown 处理程序,则应将消息发送到父级。
If you call the base OnLButtonDown handler, the message should be sent to the parent.