【问题标题】:Understanding CStatic and CWnd and message routing了解 CStatic 和 CWnd 以及消息路由
【发布时间】:2011-12-14 11:09:33
【问题描述】:

我正在尝试了解消息路由在 MFC 中的工作原理,对此我有一些疑问。想象一个扩展 CWnd 的控件。我的第一个问题是:该控件中的所有消息是否都传递给父控件?

我知道 CStatic 不会发生这种情况,它仅在您设置 SS_NOTIFY 样式时传递特定消息。我试图了解这是特定于 CStatic 还是发生在所有控件中。具体来说,我正在尝试制作一个具有多个子控件的控件,其唯一目的是定义它们的布局。我希望子控件的所有消息都由这个中间控件的父级处理。例如,如果此布局控件有一个子按钮,则当单击该按钮时,消息将发送给父级以进行处理。

但是,我不打算手动处理所有消息。那么,如果我从 CWnd 而不是 CStatic 扩展我的控制,消息会被传递吗? FORWARD_NOTIFICATIONS() 在 MFC 中可用吗?如果不是,我宁愿扩展我的中间类以根据需要处理消息。你知道的任何其他解决方案?

【问题讨论】:

    标签: c++ windows mfc cwnd


    【解决方案1】:

    消息被发送到窗口本身。

    一些窗口向它们的父级发送消息,通常以 WM_NOTIFY 消息的形式,或者(如按钮)以像 BN_CLICKED 这样的“特殊”消息的形式。

    MFC 有一个系统(“反射”系统)让窗口将这些消息发送回窗口本身,这样您就可以在控件中处理消息而不是涉及父控件。

    这大致是它在抽象中的工作方式。您想要的(让父控件处理发送给所有子控件的所有消息)通常不是您“应该”如何做的。例如,您不希望子窗口的所有 WM_PAINT 都发送给父窗口。

    您想要做的(处理按钮点击)是不同的。按钮点击由按钮以 BN_CLICKED 的形式“发出”。无论如何,这些都将由父母处理。

    如果你还是下定决心,你可以接管子窗口的 WndProc 来做一些“过滤”。通常这是使用 PreTranslateMessage() 虚函数完成的。

    【讨论】:

    • 我想要的是将由父母处理的消息由祖父母处理。将由控件处理的消息将保持不变。我希望我的容器对发送给父级的消息是透明的。
    • 好的,我现在明白了。这不能“轻松”完成,其中“轻松”意味着必须仅使用 ohe 宏左右。您必须在父级(容器)中捕获消息并手动将它们重新发送到容器的父级。但是,其中大部分可以自动化,例如通过将所有 BN_CLICKED 消息拦截到一个函数,并让该函数将它们重新发送给父级。这样您就不必在每次添加按钮时都更新容器。
    • 我可以处理 BN_CLICKED 消息并将消息发送给父级吗?如何?还是我必须发送一般通知并在父级中区分消息?
    【解决方案2】:

    您需要使用通知,这意味着发送WM_NOTIFY 消息,并在附加结构中指定您自己的代码。然后您的父控件可以使用ON_NOTIFY 处理消息,或者您可以让所有者类使用ON_NOTIFY_REFLECT 自己处理消息。

    您总是可以避免使用 Windows\MFC 消息传递体系结构,而改用基于事件的系统。像Boost.Signals2 这样的东西。在我们的应用程序中,我们混合使用 WM_NOTIFY 消息和 Boost.Signals2。

    【讨论】:

      猜你喜欢
      • 2017-02-05
      • 2015-12-10
      • 2021-01-10
      • 1970-01-01
      • 2013-05-30
      • 1970-01-01
      • 2019-10-23
      • 1970-01-01
      • 2013-05-06
      相关资源
      最近更新 更多