注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

重读深入浅出MFC(6)—消息的种类及处理方式2  

2011-07-25 15:39:12|  分类: C++(VC)编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

从一个印度工程师的封装类谈开来
在搜索资料时,从网上下来一个印度三哥的多文档多视图的封装类,写得不错,正好其消息的处理机制暗与目前MFC的框架温习有些相通,整理一下思路。
一开始把程序打开,竟然找不到对菜单命令消息的处理函数,看样子又一个不按套路出牌得来了,这个工程其实主要是写了两个文件,MvDocTemplate.cpp和MvDocTemplate.hpp,

后面这个HPP做后缀的,反正我见过得比较多的是在BaoLADN c++里面见到的比较多。里面封装了六个类,CFrameTemplate,CFrame,CSDIMVDocTemplate,CMvDocTemplate,

CMDIMVDocTemplate,CDocFrameMgr。其实最主要的是重写了文档模板类,有两个,一个是供继承的主要的CMvDocTemplate,一个供数据结构使用的CFrame,这里并不详细介绍这个

封装的使用方法,主要是讨论其中的消息处理的过程,其它请自己从网上下载此工程进行分析。
既然没有消息处理的方法,就得考虑MFC通用的消息流走的过程,所以找到了OnCmdMsg这个处理函数,其中
CDocFrameMgr::OnCmdMsg( UINT _nID, int _nCode, void* _pExtra )函数里有以下几行代码:
 CFrame* pChosenFrame = FindFrame( _nID );
    if ( _nCode == CN_COMMAND && pChosenFrame )
    {
        // Try to create the frame.
        return pChosenFrame->ShowOrCreateFrame(  );
    }
    else if ( _nCode == CN_UPDATE_COMMAND_UI && pChosenFrame )
这明显是对菜单的ID进行控制的代码。
好,接着看UINT _nID怎么来的,在BOOL CMvDocTemplate::OnCmdMsg( UINT _nID, int _nCode, void* _pExtra, AFX_CMDHANDLERINFO* _pHandlerInfo )函数里有:
  if ( pDocFrameMgr )
  {
   bProcessed = pDocFrameMgr->OnCmdMsg( _nID, _nCode, _pExtra );
  }
好,再向上看,这是在MFC的文档模板类CMultiDocTemplate的继承类里,好,万流归宗了。
我们再来看如何添加的这些个ID,在APP的初始化函数里:
    CMvDocTemplate *pDocTemplate = new CMDIMVDocTemplate( IDR_MVTESTTYPE, RUNTIME_CLASS( CMvTestDoc ) );
    pDocTemplate->AddFrameTemplate(
        new CFrameTemplate(
            IDR_MV1,
            RUNTIME_CLASS( CChildFrame1 ),
            RUNTIME_CLASS( CView1 ),
            ID_VIEW_VIEW1,
            SW_SHOWNORMAL,
            TRUE ) );
发现这段代码,在这里发现了ID_VIEW_VIEW1菜单的ID,跟进new CFrameTemplate函数,

  CFrameTemplate(
            UINT _nIDResource, CRuntimeClass* _pFrameClass, CRuntimeClass* _pViewClass,
            UINT _nEventID, UINT _nDefaultWndStatus = WS_VISIBLE,
   BOOL _bLoadAtStartup = FALSE )
  {
   m_nResourceID  = _nIDResource;
   m_pFrameClass  = _pFrameClass;
   m_pViewClass  = _pViewClass;
   m_nEventID   = _nEventID;
   m_nDefaultWndStatus = _nDefaultWndStatus;
   m_bLoadAtStartup = _bLoadAtStartup;
  }
发现了吧,不用注释也看得很清楚,这个ID_VIEW_VIEW1表示的是一个EVENT的ID,这样,就明白了,MFC将ID传下来,通过pFrame->GetEventID()与MFC传入的比较,就可以知道是

调用的哪个菜单了。当然,这里面也少不了宏的作用,理解清楚了后,试着下两个断点在CDocFrameMgr::OnCmdMsg函数中,一个在IF语句内,一个在语句外,F5,断点果然停住在

IF外的那个上面,去掉这个断点,进入界面,在界面上点击菜单或工具栏上的图标,重新拦截到IF内的断点上,查看CALL STACK如下:

CDocFrameMgr::OnCmdMsg(unsigned int 32773, int 0, void * 0x00000000) line 773
CMvDocTemplate::OnCmdMsg(unsigned int 32773, int 0, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 495 + 20 bytes
CDocument::OnCmdMsg(unsigned int 32773, int 0, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 899 + 42 bytes
CView::OnCmdMsg(unsigned int 32773, int 0, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 167 + 33 bytes
CFrameWnd::OnCmdMsg(unsigned int 32773, int 0, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 890 + 33 bytes
CWnd::OnCommand(unsigned int 32773, long 200290) line 2088
CFrameWnd::OnCommand(unsigned int 32773, long 200290) line 317
CWnd::OnWndMsg(unsigned int 273, unsigned int 32773, long 200290, long * 0x0012f600) line 1597 + 28 bytes
CWnd::WindowProc(unsigned int 273, unsigned int 32773, long 200290) line 1585 + 30 bytes
AfxCallWndProc(CWnd * 0x00433a50 {CChildFrame1 hWnd=???}, HWND__ * 0x00020dfc, unsigned int 273, unsigned int 32773, long 200290) line 215 + 26 bytes
CMDIFrameWnd::OnCommand(unsigned int 32773, long 200290) line 55 + 35 bytes
CWnd::OnWndMsg(unsigned int 273, unsigned int 32773, long 200290, long * 0x0012f7c8) line 1597 + 28 bytes
CWnd::WindowProc(unsigned int 273, unsigned int 32773, long 200290) line 1585 + 30 bytes
AfxCallWndProc(CWnd * 0x00431210 {CMainFrame hWnd=???}, HWND__ * 0x002b042a, unsigned int 273, unsigned int 32773, long 200290) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x002b042a, unsigned int 273, unsigned int 32773, long 200290) line 368
AfxWndProcBase(HWND__ * 0x002b042a, unsigned int 273, unsigned int 32773, long 200290) line 220 + 21 bytes
跑我们前文讲的消息流转的框架,何其一样。只不过个更详细,更清楚。
一点一点,抽丝剥茧!!!

  评论这张
 
阅读(882)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017