在MFC的CStatic中使用事件并将它们传递给父级

时间:2010-01-18 00:13:34

标签: events mfc event-bubbling

我正在构建MFC应用程序,其中CDialog带有源自CStatic的子控件。

我想接收CStatic控件的鼠标事件,因此我将"Notify"设置为true。现在,我可以直接通过MyStatic

中的消息地图接收消息事件

class CMyStatic : public CStatic
{
afx_msg void OnLButtonDown(UINT nFlags, CPoint point); // Gets invoked
DECLARE_MESSAGE_MAP()
}

问题是,从现在开始,当鼠标超过MyStatic子级时,父CDialog不会接收鼠标事件。我可以手动从MyStatic发送它们,但有没有办法让它们自动通过?并且仍然可以使用消息映射在MyStatic上接收它们吗?

2 个答案:

答案 0 :(得分:5)

不,你是误会。 SS_NOTIFY不会导致您的CStatic接收消息,它会导致CStatic将消息中继回父节点。所以“现在我能够直接在MyStatic中通过消息地图接收消息事件”是基于错误的前提。

这是一个重要的观点,因为控件只能接收本身的消息,而不能接收其子节点的消息,除非这些孩子通过转发消息或通过其他技巧(全局挂钩)来“播放” ,...);但这些情况是例外,“正常”的方式是每个窗口都为自己接收消息。

所以这回答了你的问题:不,没有办法让父母(你的CDialog)和孩子(你的CStatic)接收鼠标事件而不是“手动”或参与繁琐的消息路由黑客攻击。所以在你的情况下,你需要做的是GetParent() - > SendMessage(WM_LBUTTONDOWN,...)等,手动重新创建WPARAM和LPARAM值;或直接在CDialog上调用OnLButtonDown:GetParent() - > OnLButtonDown(...)。你必须考虑你传回CDialog的鼠标坐标,你可能需要将它们翻译成CDialog的客户坐标。

答案 1 :(得分:1)

如果您调用基本的OnLButtonDown处理程序,则应将消息发送给父级。

CMyStatic::OnLButtonDown(UINT nFlags, CPoint point)
{
    CStatic::OnLButtonDown(nFlags, point);

    // custom handling
}