65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 MFC 进行消息转发

starIconstarIconemptyStarIconemptyStarIconemptyStarIcon

2.00/5 (5投票s)

2005年5月4日

3分钟阅读

viewsIcon

26501

downloadIcon

316

本文提供了一个简单的类,允许您将来自 Windows 中任何控件的消息转发到公共窗口过程。

引言

您是否曾经在 MFC 中遇到过这种烦恼:您需要从窗口过程中的每个控件发送的消息? 某些消息,例如 WM_SETFOCUS,是发送而不是发布的。 因此,某些消息无法到达 PreTranslateMessage 阶段。 当您需要控件的消息时,这可能会非常烦人。 那么,解决方案是什么? 您需要为要获取其消息的每个控件派生一个新类,并重写 WindowProc。 这很令人沮丧,不是吗? 然而……正因为如此,我花了一些时间来设计一个解决方案。 现在您只需从一个类派生要获取其消息的每个控件即可。 该类将自动将其收到的任何消息转发到自定义 WindowProc。 这非常小巧简单,但却非常强大! 通过函数指针和模板,我向您展示这段代码...

代码可供下载。 您只需要包含头文件并派生您的类。 尽管它们也需要初始化。 但是,您可以在构造函数的初始化列表中完成此操作 ^_^。

至于代码的工作方式... 很容易。 使用模板,您必须指定父类、要使用的函数指针以及要调用其函数的类。 使用此方法,它会在其 WindowProc 中回调到指定的类和函数。 简单!

我将演示如何使用它...

#include "MsgForward.h"
typedef LRESULT (CMainDlg::*ProcPtr)(CWnd*, UINT, WPARAM, LPARAM);

class CMainDlg: public CDialog
{
  public:
    CMsgForward<CEdit,ProcPtr,CMainDlg> m_MyEdit; 
  protected:
    LRESULT WindowProc(CWnd* pCtrl, UINT message, WPARAM wParam, LPARAM lParam);
}

CMainDlg::CMainDlg() :
m_MyEdit(WindowProc,this,PROCESS_AFTER)
{ }

就这么简单! 现在,让我解释一下... 由于它使用模板,我们必须指定类型。 第一个类型是父类。 此类派生自父类,因此保留了对象应该具备的所有功能! 第二个是函数指针,指向您将用于将消息转发到的函数。 它必须是一个如上所述的 WindowProc。 它就像一个普通的 WindowProc,但第一个参数是发送消息的控件。 模板的第三个参数是函数所在的类。

现在是构造函数...所有参数都是可选的。 但如果没有前两个参数,它将无法且不会转发任何消息。 第一个参数是要接收消息的函数的地址。 第二个参数是函数所在的类(通常由 this 指针指向)。 还要记住:通常不建议将 this 指针传递给构造函数的初始化器。 您很可能会收到编译器的警告。 但在这里是完全安全的! 至于第三个参数,也是可选的...它指定了消息的处理方式。

有三个选项

  • PROCESS_BEFORE - 所有消息都将转发到基类进行处理,然后转发到您的函数。
  • PROCESS_AFTER - 与这里相同,但它是在发送到您的函数之后
  • DONOT_PROCESS - 没有任何消息被转发到基类进行处理 - 注意这个! 不推荐。

默认值为 PROCESS_AFTER。 如果您希望基类在您拦截它们之前处理消息,您可能希望为某些控件更改此设置。 您可以随时更改类的 eMsgProcessing 变量来更改此行为。 您还可以通过操作公共变量来更改类和函数的地址。

哦,如果您问我为什么使用公共变量(是的,我知道这是一个糟糕的编程),事实是我不在乎 =)。 我认为它没有任何错误,并且发现为所有需要操作的变量创建 Set/Get 很烦人。 随意更改。

而这,我的朋友们...就是关于它的全部内容了。 现在您可以拦截所有这些消息。 一如既往,编码愉快,如果您有任何缺陷或您想讨论的其他内容,请随时发表评论。

© . All rights reserved.