使用 MFC 进行消息转发





2.00/5 (5投票s)
2005年5月4日
3分钟阅读

26501

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