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

发布于 2024-08-18 04:13:56 字数 466 浏览 11 评论 0原文

我正在构建 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一人独醉 2024-08-25 04:13:56

不,你误会了。 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.

绮筵 2024-08-25 04:13:56

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

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

    // custom handling
}

If you call the base OnLButtonDown handler, the message should be sent to the parent.

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

    // custom handling
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文