金山界面库分析(6)
消息和事件的传递、分发、相应
既然没有真实的窗口,那么也就不能使用windows的根据句柄来分发消息的方式了,我们需要创建自己的消息和事件分发体系。主要应该包括这几个方面:
1. 接收真实窗口的消息,并将其转化虚窗口体系中的处理
2. 虚窗口体系内有一套独立的消息分发机制,可以讲系统消息发至该接收的控件
3. 虚窗口需要能够抛出事件的能力,因为虚窗口之间也需要有相互的通知和相应的能力,那么就需要虚窗口可以对于指定窗口抛出事件
4. 对于3中所抛出的事件,可以传递到指定的控件,并且控件内部应该有一套指定额相应体系
在CBkDialogViewImpl中使用WTL的消息分发方法用于系统消息的分发:
BEGIN_MSG_MAP_EX(CBkDialogViewImpl)
MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST,WM_MOUSELAST,OnToolTipEvent)
MSG_WM_SIZE(OnSize)
MSG_WM_PRINT(OnPrint)
MSG_WM_PAINT(OnPaint)
//……从略
NOTIFY_CODE_HANDLER_EX(BKINM_INVALIDATERECT,OnBKINMInvalidateRect)
REFLECT_NOTIFY_CODE(NM_CUSTOMDRAW)
MESSAGE_HANDLER_EX(WM_NOTIFY,OnChildNotify)
MESSAGE_HANDLER_EX(WM_COMMAND,OnChildNotify)
MESSAGE_HANDLER_EX(WM_VSCROLL,OnChildNotify)
MESSAGE_HANDLER_EX(WM_HSCROLL,OnChildNotify)
REFLECT_NOTIFICATIONS_EX()
END_MSG_MAP()
下面的是对于WM_SIZE消息的分发过程:

在CBkWindow类中创建了用于发送通知的函数:
我们点击调用栈里面的ProcessWindowMessage方法,程序转到了CBkWindow类的这块:
BKWIN_BEGIN_MSG_MAP()
MSG_WM_CREATE(OnCreate)
MSG_WM_PAINT(OnPaint)
MSG_WM_DESTROY(OnDestroy)
MSG_WM_WINDOWPOSCHANGED(OnWindowPosChanged)
MSG_WM_NCCALCSIZE(OnNcCalcSize)
MSG_WM_SHOWWINDOW(OnShowWindow)
BKWIN_END_MSG_MAP_BASE()
难道就是这串宏实现了实现了通知的相应机制,我们来分析一下这个几个宏的实现。
protected: virtualBOOL ProcessWindowMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult) { if(uMsg == WM_CREATE) { SetMsgHandled(TRUE); lResult= (LRESULT)func((LPCREATESTRUCT)lParam); if(IsMsgHandled()) returnTRUE; } //......此处略去其他分发函数 if (!IsMsgHandled()) return__super::ProcessWindowMessage( hWnd, uMsg, wParam, lParam,lResult); return TRUE; }__super::ProcessWindowMessage完整的链式消息传递啊~~,对于子类处理之后的消息还行传递给父类进行处理就可以这么搞了~~~