码迷,mamicode.com
首页 > 编程语言 > 详细

Win32 与MFC

时间:2014-10-24 16:52:53      阅读:307      评论:0      收藏:0      [点我收藏+]

标签:mfc

Win32:

         Win32函数式编程,窗口体系,消息统一传入反应函数处理

 

通过分析MFC的源代码,我们可以得到WM_COMMAND的消息响应顺序如下:

多文档框架中,有打开的文档时:视图 > 文档 > 子框架窗口 > 应用程序 >主框架窗口

多文档框架在没有打开文档时,应用程序和主框架窗口的顺序相反:主框架窗口 > 应用程序

 

在单文档框架应用程序中,因为没有子框架窗口,所以顺序应该是:视图 > 文档 >主框架窗口> 应用程序。无论有没有打开文档,主框架窗口都比应用程序类更优先。

事实上在多文档框架中,系统自动生成的代码使用的是CDocTemplate的子类CMultiDocTemplate。在应用程序类(多文档应用框架)的InitInstance()里可以找到类似下面的代码:

bubuko.com,布布扣    // 注册应用程序的文档模板。文档模板
bubuko.com,布布扣    
// 将用作文档、框架窗口和视图之间的连接
bubuko.com,布布扣
    CMultiDocTemplate* pDocTemplate;
bubuko.com,布布扣    pDocTemplate 
= new CMultiDocTemplate(IDR_test3TYPE,
bubuko.com,布布扣       RUNTIME_CLASS(Ctest3Doc),
bubuko.com,布布扣       RUNTIME_CLASS(CChildFrame), 
// 自定义 MDI 子框架
bubuko.com,布布扣
       RUNTIME_CLASS(Ctest3View));
bubuko.com,布布扣    
if (!pDocTemplate)
bubuko.com,布布扣       
return FALSE;
bubuko.com,布布扣

而CMultiDocTemplate类并没有重写OnCmdMsg函数,所以依然不影响WM_COMMAND消息的响应顺序。

bubuko.com,布布扣BOOL CDocTemplate::OnCmdMsg(UINT nID, int nCode, void* pExtra,
bubuko.com,布布扣    AFX_CMDHANDLERINFO
* pHandlerInfo)
bubuko.com,布布扣bubuko.com,布布扣
...{
bubuko.com,布布扣    BOOL bReturn;
bubuko.com,布布扣    CCmdTarget
* pFactory = DYNAMIC_DOWNCAST(CCmdTarget, m_pAttachedFactory);
bubuko.com,布布扣 
bubuko.com,布布扣    
if (nCode == CN_OLE_UNREGISTER && pFactory != NULL)
bubuko.com,布布扣       bReturn 
= pFactory->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
bubuko.com,布布扣    
else
bubuko.com,布布扣       bReturn 
= CCmdTarget::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
bubuko.com,布布扣 
bubuko.com,布布扣    
return bReturn;
bubuko.com,布布扣}

bubuko.com,布布扣

因为应用程序中并没有开发直接从CDocTemplate继承的类,所以应用程序无法使用CDocTemplate的子类定义WM_COMMAND消息的响应函数。CDocTemplate类在OnCmdMsg函数实现里调用的CCmdTarget::OnCmdMsg实现不了任何消息的传递。

视图CView > 文档CDocument > 子框架CFrame > 应用程序CWinApp >主框架窗口CMDIFrameWnd

 

再查看CDocument的OnCmdMsg的实现代码:

bubuko.com,布布扣BOOL CDocument::OnCmdMsg(UINT nID, int nCode, void* pExtra,
bubuko.com,布布扣    AFX_CMDHANDLERINFO
* pHandlerInfo)
bubuko.com,布布扣bubuko.com,布布扣
...{
bubuko.com,布布扣    
if (CCmdTarget::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
bubuko.com,布布扣       
return TRUE;
bubuko.com,布布扣 
bubuko.com,布布扣    
// otherwise check template
bubuko.com,布布扣
    if (m_pDocTemplate != NULL &&
bubuko.com,布布扣     m_pDocTemplate
->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
bubuko.com,布布扣       
return TRUE;
bubuko.com,布布扣 
bubuko.com,布布扣    
return FALSE;
bubuko.com,布布扣}

bubuko.com,布布扣

文档类CDocument首先查找自己的响应函数(调用CCmdTarget::OnCmdMsg),然后让其成员m_pDocTemplate来处理。m_pDocTemplate是文档模板类CDocTemplate的指针,MFC框架使用文档模板来实现自动化的文档管理。在应用程序开发过程中,没有针对文档模板类的编程。查看CDocTemplate类中OnCmdMsg的实现:

存在打开的视图时,视图CView > 子框架CFrame > 应用程序CWinApp >主框架窗口CMDIFrameWnd

没有打开视图时,主框架窗口CMDIFrameWnd > 应用程序CWinApp

 

再看视图CView类对OnCmdMsg的处理:

bubuko.com,布布扣BOOL CView::OnCmdMsg(UINT nID, int nCode, void* pExtra,
bubuko.com,布布扣    AFX_CMDHANDLERINFO
* pHandlerInfo)
bubuko.com,布布扣bubuko.com,布布扣
...{
bubuko.com,布布扣    
// first pump through pane
bubuko.com,布布扣
    if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
bubuko.com,布布扣       
return TRUE;
bubuko.com,布布扣 
bubuko.com,布布扣    
// then pump through document
bubuko.com,布布扣
    if (m_pDocument != NULL)
bubuko.com,布布扣bubuko.com,布布扣    
...{
bubuko.com,布布扣       
// special state for saving view before routing to document
bubuko.com,布布扣
       CPushRoutingView push(this);
bubuko.com,布布扣       
return m_pDocument->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
bubuko.com,布布扣    }

bubuko.com,布布扣 
bubuko.com,布布扣    
return FALSE;
bubuko.com,布布扣}

bubuko.com,布布扣

视图类首先查找自己的消息响应表(调用CWnd::OnCmdMsg),然后让视图对应的CDocument类处理消息。所以可以得出如下顺:

子框架窗口CMDIChildWnd > 主框架窗口CMDIFrameWnd

 

CMDIChildWnd窗口没有重载OnCmdMsg函数,所以使用基本框架窗口CFrameWnd的OnCmdMsg函数:

bubuko.com,布布扣BOOL CFrameWnd::OnCmdMsg(UINT nID, int nCode, void* pExtra,
bubuko.com,布布扣    AFX_CMDHANDLERINFO
* pHandlerInfo)
bubuko.com,布布扣bubuko.com,布布扣
...{
bubuko.com,布布扣    CPushRoutingFrame push(
this);
bubuko.com,布布扣 
bubuko.com,布布扣    
// pump through current view FIRST
bubuko.com,布布扣
    CView* pView = GetActiveView();
bubuko.com,布布扣    
if (pView != NULL && pView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
bubuko.com,布布扣       
return TRUE;
bubuko.com,布布扣 
bubuko.com,布布扣    
// then pump through frame
bubuko.com,布布扣
    if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
bubuko.com,布布扣       
return TRUE;
bubuko.com,布布扣 
bubuko.com,布布扣    
// last but not least, pump through app
bubuko.com,布布扣
    CWinApp* pApp = AfxGetApp();
bubuko.com,布布扣    
if (pApp != NULL && pApp->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
bubuko.com,布布扣       
return TRUE;
bubuko.com,布布扣 
bubuko.com,布布扣    
return FALSE;
bubuko.com,布布扣}

bubuko.com,布布扣

基本框架窗口先让当前活动视图CView响应函数,然后再查找自己的消息响应表(调用CWnd::OnCmdMsg),最后让应用程序处理该消息。所以得出顺序:

MFC:

        Win32的封装,窗口体系单元化,单元子父类绘制关系体系和消息响应机制,分别是互绘制机制和

消息传递机制

       

在MFC开发的程序中,菜单、工具条按钮等都会产生WM_COMMAND消息。而在MFC的Document/View框架中,有很多类可以响应WM_COMMAND消息,分别是框架类:CFrameWnd、CMDIChildWndCMDIFrameWnd;应用程序类CWinApp;文档类CDocument;以及视图类CView。

当应用程序主菜单发送了一个WM_COMMAND消息时,WM_COMMAND消息将会按一定顺序被交这些类的实例,并调用第一个发现的响应函数。以多文档视图框架应用程序为例,我们可以分析MFC中这些类的源代码,并一步一步找出WM_COMMAND消息的响应顺序。

因为框架窗口是菜单的父窗口,所以消息首先发到CMDIFrameWnd类的实例(也就是主框架窗口,通常为CMainFrame)。CMDIFrameWnd类的OnCmdMsg函数如下:

bubuko.com,布布扣BOOL CMDIFrameWnd::OnCmdMsg(UINT nID, int nCode, void* pExtra,
bubuko.com,布布扣    AFX_CMDHANDLERINFO
* pHandlerInfo)
bubuko.com,布布扣bubuko.com,布布扣
...{
bubuko.com,布布扣    CMDIChildWnd
* pActiveChild = MDIGetActive();
bubuko.com,布布扣    
// pump through active child FIRST
bubuko.com,布布扣
    if (pActiveChild != NULL)
bubuko.com,布布扣bubuko.com,布布扣    
...{
bubuko.com,布布扣       CPushRoutingFrame push(
this);
bubuko.com,布布扣       
if (pActiveChild->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
bubuko.com,布布扣           
return TRUE;
bubuko.com,布布扣    }

bubuko.com,布布扣 
bubuko.com,布布扣    
// then pump through normal frame
bubuko.com,布布扣
    return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
bubuko.com,布布扣}

bubuko.com,布布扣

主框架窗口CMDIFrameWnd先查找当前活动的子框架窗口CMDIChildWnd,让其优先访问,然后调用基本框架窗口CFrameWnd的响应函数。所以响应优先级:

 

Win32 与MFC

标签:mfc

原文地址:http://embeded.blog.51cto.com/3989210/1567479

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!