MFC教程(5)-- MFC对象的创建(2)
2010-03-25 20:33:44 来源:WEB开发网WM_CREATE的处理函数不同
创建MDI子窗口时发送的WM_CREATE消息由CMDIChildWnd的成员函数OnCreate(LPCREATESTRUCT lpCreateStruct)处理。
OnCreate函数仅仅从lpCreateStruct指向的数据中取出窗口创建数据,即指向MDICREATESTRUCT结构的指针,并从该结构得到指向CCreateContext结构的指针pContext,然后调用虚拟函数OnCreateHelper(lpCreateStruct,pContext)。
此处动态约束的结果是调用了CFrameWnd的成员函数OnCreateHelper。SDI应用程序的OnCreate也调用了CFrameWnd::OnCreateHelper,所以后面的处理(创建视等)可参见SDI的流程了。
待MDI子窗口、视、文档对象创建完毕,多文档模板的OpenDocumentFile也调用InitialUpdateFrame来进行初始化。
MDI子窗口的初始化和窗口的激活
(1)MDI子窗口的初始化
完成了 MDI子窗口、视、文档的创建之后,多文档模板的OpenDocumenFile调用边框窗口的虚拟函数InitialUpdateFrame进行初始化,该函数流程参见图5-14。不过,这里this指针指向CMDIChildWnd对象,由于C++虚拟函数的动态约束,初始化过程调用了CMDIChildWnd的ActivateFrame函数(不是CFrameWnd的ActivateFrame),来显示MDI子窗口,更新菜单等等,见图5-18。
图5-18的说明:
第一,调用基类CFrameWnd的ActivateFrame显示窗口时,由于当前窗口是文档边框窗口,所以没有发送WM_ACTIVATE消息,而是发送消息WM_MDIACTIVATE。
第二,由于Windows不处理MDI子窗口的激活,所以必须由MFC或者程序员来完成。当一个激活的MDI子窗口被隐藏后从可见变成不可见,但它仍然是活动的,这时需要把下一文档边框窗口激活以便用户看到的就是激活的窗口。在没有其他文档边框窗口时,则把该隐藏的文档边框窗口标记为“伪失去激活”。当一个文档边框窗口从不可见变成可见时,检查变量m_bPseudoInactive,若真则该窗口从Windows角度看仍然是激活的,只需要调用OnMDIActivate把它改成“MFC激活”。OnMDIActivate把变量m_bPseudoInactive的值改变为FALSE。
至此,MDI子窗口初始化调用描述完毕。初始化将导致MDI窗口被显示、激活。下面讨论MDI子窗口的激活。
(2)MDI子窗口的激活
通过给客户窗口发送消息WM_MDIACTIVATE来激活文档边框窗口。客户窗口发送WM_MDIACTIVATE消息给将被激活或者取消激活的MDI子窗口(文档边框窗口),这些子窗口调用消息处理函数OnMDIActivate响应该消息WM_MDIACTIVATE。关于MDI消息,见表5-12。
用户转向一个子窗口(包括文档边框窗口)导致它的顶层(TOP LEVEL)边框窗口收到WM_ACTIVATE消息而被激活,子窗口是文档边框窗口的话将收到WM_MDIACTIVATE消息。
但是,一个边框窗口被其他方式激活时,它的文档边框窗口不会收到WM_MDIACTIVATE消息,而是最近一次被激活的文档边框窗口收到WM_NCACTIVATE消息。该消息由CWnd::Default缺省处理,用来重绘文档边框窗口的标题栏、边框等等。
MDI子窗口用OnMDIActiveate函数处理WM_MDIACTIVATE消息。其原型如下:
void CMDIChildWnd::OnMDIActivate( BOOL bActivate,
CWnd* pActivateWnd,CWnd* pDeactivateWnd );
其中:
参数1表示是激活(TRUE),还是失去激活(FALSE);
参数2表示将被激活的MDI子窗口;
参数3表示将被失去激活的MDI子窗口;
简单地说,该函数把m_bPseudoInactive的值改变为FALSE,调用成员函数OnActivateView通知失去激活的子窗口的视它将失去激活,调用成员函数OnActivateView通知激活子窗口的视它将被激活。
至于MDI主边框窗口,它还是响应WM_ACTIVATE消息而被激活或相反。CMDIFrameWnd没有提供该消息的处理函数,它调用基类CFrameWnd的处理函数OnActivate。
现在,MDI应用程序的启动过程描述完毕。
表5-12 MDI消息
消息 | 说明 |
WM_MDIACTIVATE | 激活MDI Child窗口 |
WM_MDICASCADE | CASCADE排列MDI Child窗口 |
WM_MDICREATE | 创建MDI Child窗口 |
WM_MDIDESTROY | 销毁MDI Child窗口 |
WM_MDIGETACTIVE | 得到活动的MDI Child窗口 |
WM_MDIICONARRANGE | 安排最小化了的MDI Child窗口 |
WM_MDIMAXIMIZE | MDI Child窗口最大化 |
WM_MDINEXT | 激活Z轴顺序的下一MDI Child窗口 |
WM_MDIREFRESHMENU | 根据当前MDI Child窗口更新菜单 |
WM_MDIRESTORE | 恢复MDI Child窗口 |
WM_MDISETMENU | 根据当前MDI Child窗口设置菜单 |
WM_MDITITLE | TITLE安排MDI Child窗口 |
更多精彩
赞助商链接