解决子窗口(视图)截获父窗口消息的2个办法(MFC)

这样的需求:

1.如果想在CView里面截获发给子框架Frame的消息怎么办?

2.假如子窗口拆分视图了, 那还得细分, 是所有视图都想截获消息,还是某个特定的视图想截获某个特定的消息.

 

对于需求1:

办法1.是重载子框架Frame的WindowProc(UINT message, WPARAM wParam, LPARAM lParam)函数,将自定义的消息(大于WM_USER)转发给自己的视图,可以SendMessage

办法2.是在视图中利用钩子来截获父窗口消息,即SubclassWindow或SetWindowLong方法,具体做法如下:

 SubclassWindow:

 1.添加一个CWnd窗口子类MessageWnd,在View中定义一个类MessageWnd的成员m_messageWnd用来接收消息;

 2.View::OnCreate中 m_messageWnd.SubclassWindow(GetParentFrame()->GetSafeHwnd());

 3.View::OnDestroy()中 m_messageWnd.UnsubclassWindow();

SetWindowLong:

 其实MFC提供的SubclassWindow并不是很适用于这个场合, SubclassWindow很适用的一个例子是: CEdit只能输入特   定的字符如只能a-z, 此时添加一个类,在OnChar中把非a-z的字符都忽略不处理. 总结一下大概就是说如果原来已经实现该消息的处理方法,但现在需要新的处理方法,这时用SubclassWindow合适. 而在这要定义一个窗口类,在其消息函数截获到消息后还得把消息返回给View来处理. 那么其实用SetWindowLong将更加简单:

 1.在View中定义一个窗口处理函数NewWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam), 此函数内将截获到消息.若其他消息则尽量让原窗口函数处理

 2. OnCreate注册新的处理函数 m_oldWndProc = (WNDPROC)SetWindowLong(GetParentFrame()->GetSafeHwnd(),GWL_WNDPROC,(LONG)NewWndProc);

 3.不能忘了,在OnDestroy时换成原来的处理函数SetWindowLong(GetParentFrame()->GetSafeHwnd(),GWL_WNDPROC,(LONG)m_oldWndProc);

此外网上也有现成的工具类, 这个工具类提供了不错的接口Hook/Unhook: http://www.cppblog.com/qinqing1984/archive/2011/12/11/161915.aspx.

 

对于需求2

 1.若所有视图都想截获消息,那用办法1较方便.一次性搞定.

 2.若个别视图想截获消息,那用办法2较适合.

 

题外话: 对于上述需求,为何不直接用文档来更新视图?

这个问题也曾考虑过. 先说一下软件情况: 有一个工作线程不停的采集数据并交给文档,文档根据不同类型采取对应方式来更新视图, 直接用UpdateAllView的话对于区分类型做不到. 如果有好的建议欢迎回复.

你可能感兴趣的:(MFC,c++,Windows)