如何将消息路由到控件的标准WNDPROC

时间:2013-03-06 16:13:30

标签: windows winapi mfc message wndproc

当创建标准窗口控件(例如"EDIT"控件)时,其WNDPROC被定义为窗口类的一部分(即"EDIT"具有特定的WNDPROC设计用于使窗口显示和表现为编辑控件。

MFC允许您通过其包装类与这些控件进行交互,例如CEdit包装"EDIT"窗口控件的专用消息。

MFC进一步允许您将"EDIT"窗口的实例绑定到CEdit的C ++子类,比如CMyEdit,您可以在其中覆盖CEdit和{{的继承虚函数1}},您可以定义一个消息表来获取发送到窗口实例本身的访问/覆盖消息。

CWnd::Default(),它使用当前的消息参数调用this-> DefWndProc。这似乎在CWnd查找与其关联的HWND。这是正确的答案:调用DefWndProc()(或同样地,默认()),它会将其移交给Windows控件的WNDPROC

显然,这与其他消息表处理程序不同,后者可以返回FALSE以指示它们不处理消息,并且MFC将自动将消息沿类继承层次结构路由到此消息的下一个消息处理程序,或者我假设,Default()由本地WNDPROC处理?

如果我定义了一个任意的消息处理程序,比如WM_SETTEXT,那么将此消息传递给WNDPROC "EDIT"的正确方法是什么?

我也想知道是否有办法将消息传递给超类(C ++类层次结构)进行处理?许多OnXXX样式处理程序确实有这样做,但是有一种适用于ON_MESSAGE处理程序的机制吗?

WNDPROC

澄清

您可以在C ++级别拥有多个MFC子类 -

所以C继承B继承A,其中A是MFC类(例如class CDynamicMenuControlEdit : public CEdit { ... LRESULT OnSetText(WPARAM wParam, LPARAM lParam); ... } BEGIN_MESSAGE_MAP(CDynamicMenuControlEdit, CEdit) ... ON_MESSAGE(WM_SETTEXT, OnSetText) ... END_MESSAGE_MAP() LRESULT CDynamicMenuControlEdit::OnSetText( WPARAM wParam, // not used; must be zero LPARAM lParam // window-text string (LPCTSTR) ) { if (m_bHasFocus) { // do normal thing // !!! THIS IS MY QUESTION: IS THIS CALLING EDIT's WNDPROC, or ::DefWinProc()? !!! return DefWindowProc(WM_SETTEXT, wParam, lParam); } ... } )。

每个都可以有一个MFC消息表 - 即CEdit ... BEGIN_MESSAGE_MAP,每个消息都可以有任意窗口消息的处理程序,例如END_MESSAGE_MAP - 和{ {1}}成员不一定是虚拟的 - 只是一个静态成员(每个MFC子类都可以以任意方式路由该消息)。

我的问题是 - 由于WM_MESSAGE(WM_SETTEXT, OnSetText)调度条目没有返回值,如何允许MFC在返回真实窗口之前将MFC调度表从C传递到B到A'编辑'类的wndproc?

或者MFC设计级别的所有这些条目都不是为了走路?即大多数子层的调度程序是唯一一个被调用的调度程序?如果它想利用一个继承的成员,它必须手动进行该调用 - MFC根本没有任何特定的通用结构吗?

2 个答案:

答案 0 :(得分:3)

调用Default()将导致响应消息发生时发生的“正常”处理。我并不完全清楚你想要实现的目标,但在我看来,调用Default()就是你想要做的。

如果您查看CWnd处理程序中的Windows消息中的许多处理程序(以及来自CWnd的类的处理程序,例如CEdit),您会看到他们调用{ {1}}。

明智的话,Default()实际上会使用原始消息的任何参数 - 你无法改变它们。

答案 1 :(得分:2)

你做得对。 CWnd :: DefWindowProc()使用你子类化的WINDOWPROC,并将调用EDIT窗口的窗口过程。