MFC视图结构框架分析.docx

上传人:b****4 文档编号:11607178 上传时间:2023-03-28 格式:DOCX 页数:25 大小:24.37KB
下载 相关 举报
MFC视图结构框架分析.docx_第1页
第1页 / 共25页
MFC视图结构框架分析.docx_第2页
第2页 / 共25页
MFC视图结构框架分析.docx_第3页
第3页 / 共25页
MFC视图结构框架分析.docx_第4页
第4页 / 共25页
MFC视图结构框架分析.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

MFC视图结构框架分析.docx

《MFC视图结构框架分析.docx》由会员分享,可在线阅读,更多相关《MFC视图结构框架分析.docx(25页珍藏版)》请在冰豆网上搜索。

MFC视图结构框架分析.docx

MFC视图结构框架分析

MFC文档视图结构框架分析

1:

程序的“导火索”---theApp

CmyApptheApp;

在声明对象的同时,调用其构造函数。

按C++的语法,首先要调用其基类Cwinapp的构造函数.这个文件主要用于应用程序的一些初始化操作。

classCWinApp:

publicCWinThread

{

   DECLARE_DYNAMIC(CWinApp)

public:

//Constructor

   CWinApp(LPCTSTRlpszAppName=NULL); 

…………

}

 

CWinApp:

:

CWinApp(LPCTSTRlpszAppName)

{

   if(lpszAppName!

=NULL)

      m_pszAppName=_tcsdup(lpszAppName);

   else

      m_pszAppName=NULL;

   //initializeCWinThreadstate

   AFX_MODULE_STATE*pModuleState=_AFX_CMDTARGET_GETSTATE();

   AFX_MODULE_THREAD_STATE*pThreadState=pModuleState->m_thread;

   ASSERT(AfxGetThread()==NULL);

   pThreadState->m_pCurrentWinThread=this;

   ASSERT(AfxGetThread()==this);

   m_hThread=:

:

GetCurrentThread();

   m_nThreadID=:

:

GetCurrentThreadId();

   //initializeCWinAppstate

   ASSERT(afxCurrentWinApp==NULL);//onlyoneCWinAppobjectplease

   pModuleState->m_pCurrentWinApp=this;

   ASSERT(AfxGetApp()==this);

   //innon-runningstateuntilWinMain

   m_hInstance=NULL;

   m_hLangResourceDLL=NULL;

   m_pszHelp=NULL;

   m_pszPro=NULL;

   m_pszRegistryKey=NULL;

   m_pszExeName=NULL;

   m_pRecent=NULL;

   m_pDocManager=NULL;

   m_atomApp=m_atomSystemTopic=NULL;

   m_lpCmdLine=NULL;

   m_pCmdInfo=NULL;

   //initializewaitcursorstate

   m_nWaitCursorCount=0;

   m_hcurWaitCursorRestore=NULL;

   //initializecurrentprinterstate

   m_hDevMode=NULL;

   m_hDevNames=NULL;

   m_nNumPreviewPages=0;    //notspecified(defaultsto1)

   //initializeDAOstate

   m_lpfnDaoTerm=NULL;  //willbesetifAfxDaoInitcalled

   //otherinitialization

   m_bHelpMode=FALSE;

   m_eHelpType=afxWinHelp;

   m_nSafetyPoolSize=512;       //defaultsize

}

2:

theApp之后的隐藏代码,由他控制整个程序的流程。

_tWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,

   LPTSTRlpCmdLine,intnCmdShow)

{

   //callshared/exportedWinMain

   returnAfxWinMain(hInstance,hPrevInstance,lpCmdLine,nCmdShow);

}

 

其中有宏定义:

#define_tWinMain  wWinMain

 

intAFXAPIAfxWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,

   LPTSTRlpCmdLine,intnCmdShow)

{

   ASSERT(hPrevInstance==NULL);

   intnReturnCode=-1;

   CWinThread*pThread=AfxGetThread();;//CWinApp是从CWinThread派生的,

   CWinApp*pApp=AfxGetApp(); //实质上就是pThread==pApp

   //AFXinternalinitialization

   if(!

AfxWinInit(hInstance,hPrevInstance,lpCmdLine,nCmdShow)) //用于初始化

      gotoInitFailure;

   //Appglobalinitializations(rare)

   if(pApp!

=NULL&&!

pApp->InitApplication())  //用于初始化

      gotoInitFailure;

   //Performspecificinitializations

   if(!

pThread->InitInstance())  //注意多态性 virtualBOOLInitInstance();

                                  //又因为pThread==pApp,所以调用pApp->InitInstance()

   {

      if(pThread->m_pMainWnd!

=NULL)

      {

          TRACE(traceAppMsg,0,"Warning:

Destroyingnon-NULLm_pMainWnd\n");

          pThread->m_pMainWnd->DestroyWindow();

      }

      nReturnCode=pThread->ExitInstance();

      gotoInitFailure;

   }

   nReturnCode=pThread->Run(); //控制消息循环

InitFailure:

#ifdef_DEBUG

   //CheckformissingAfxLockTempMapcalls

   if(AfxGetModuleThreadState()->m_nTempMapLock!

=0)

   {

      TRACE(traceAppMsg,0,"Warning:

Tempmaplockcountnon-zero(%ld).\n",

          AfxGetModuleThreadState()->m_nTempMapLock);

   }

   AfxLockTempMaps();

   AfxUnlockTempMaps(-1);

#endif

   AfxWinTerm();

   returnnReturnCode;

}

由上面的程序可以看到几个很重要的函数

(1)AfxWinInit(hInstance,hPrevInstance,lpCmdLine,nCmdShow))

      gotoInitFailure;

 

(2)pApp->InitApplication())

 (3)pThread->InitInstance()

 (4)pThread->Run()

其中1,2也是完成程序的一些初始化工作,4主要是为了处理消息,3呢,很关键,我们运行时看到的窗口就是从这里产生。

下面一一介绍

3:

程序自动产生的InitInstance()函数

以下是自动生成的InitInstance()源程序:

BOOLCmyApp:

:

InitInstance()

   {

   //如果一个运行在WindowsXP上的应用程序清单指定要

   //使用ComCtl32.dll版本6或更高版本来启用可视化方式,

   //则需要InitCommonControls()。

否则,将无法创建窗口。

   InitCommonControls();

   CWinApp:

:

InitInstance();

   //初始化OLE库

   if(!

AfxOleInit())

   {

      AfxMessageBox(IDP_OLE_INIT_FAILED);

      returnFALSE;

   }

   AfxEnableControlContainer();

   //标准初始化

   //如果未使用这些功能并希望减小

   //最终可执行文件的大小,则应移除下列

   //不需要的特定初始化例程

   //更改用于存储设置的注册表项

   //TODO:

应适当修改该字符串,

   //例如修改为公司或组织名

   SetRegistryKey(_T("应用程序向导生成的本地应用程序"));

   LoadStdPro(4); //加载标准INI文件选项(包括MRU)

   //注册应用程序的文档模板。

文档模板

   //将用作文档、框架窗口和视图之间的连接

   CMultiDocTemplate*pDocTemplate;

   pDocTemplate=newCMultiDocTemplate(IDR_myTYPE,

      RUNTIME_CLASS(CmyDoc),

      RUNTIME_CLASS(CChildFrame),//自定义MDI子框架

      RUNTIME_CLASS(CmyView));

   if(!

pDocTemplate)

      returnFALSE;

   AddDocTemplate(pDocTemplate);

   //创建主MDI框架窗口

   CMainFrame*pMainFrame=newCMainFrame;

   if(!

pMainFrame||!

pMainFrame->LoadFrame(IDR_MAINFRAME))

      returnFALSE;

   m_pMainWnd=pMainFrame;

   //仅当具有后缀时才调用DragAcceptFiles

   // 在MDI应用程序中,这应在设置m_pMainWnd之后立即发生

   //分析标准外壳命令、DDE、打开文件操作的命令行

   CCommandLineInfocmdInfo;

   ParseCommandLine(cmdInfo);

   //调度在命令行中指定的命令。

如果

   //用/RegServer、/Register、/Unregserver或/Unregister启动应用程序,则返回FALSE。

   if(!

ProcessShellCommand(cmdInfo))  //引发窗口注册

      returnFALSE;

   //主窗口已初始化,因此显示它并对其进行更新

   pMainFrame->ShowWindow(m_nCmdShow);

   pMainFrame->UpdateWindow();

   returnTRUE;

}

 

其中,注册窗口用到了一下函数,比较长,如下:

BOOLAFXAPIAfxEndDeferRegisterClass(LONGfToRegister)

{

   //maskoffallclassesthatarealreadyregistered

   AFX_MODULE_STATE*pModuleState=AfxGetModuleState();

   fToRegister&=~pModuleState->m_fRegisteredClasses;

   if(fToRegister==0)

      returnTRUE;

   LONGfRegisteredClasses=0;

   //commoninitialization

   WNDCLASSwndcls;

   memset(&wndcls,0,sizeof(WNDCLASS));  //startwithNULLdefaults

   wndcls.lpfnWndProc=DefWindowProc;   //窗口处理函数

   wndcls.hInstance=AfxGetInstanceHandle();

   wndcls.hCursor=afxData.hcurArrow;

 

   INITCOMMONCONTROLSEXinit;

   init.dwSize=sizeof(init);

 

   //worktoregisterclassesasspecifiedbyfToRegister,populatefRegisteredClassesaswego

   if(fToRegister&AFX_WND_REG)

   {

      //Childwindows-nobrush,noicon,safestdefaultclassstyles

      wndcls.style=CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;

      wndcls.lpszClassName=_afxWnd;

      if(AfxRegisterClass(&wndcls))

          fRegisteredClasses|=AFX_WND_REG;

   }

   if(fToRegister&AFX_WNDOLECONTROL_REG)

   {

      //OLEControlwindows-useparentDCforspeed

      wndcls.style|=CS_PARENTDC|CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;

      wndcls.lpszClassName=_afxWndOleControl;

      if(AfxRegisterClass(&wndcls))

          fRegisteredClasses|=AFX_WNDOLECONTROL_REG;

   }

   if(fToRegister&AFX_WNDCONTROLBAR_REG)

   {

      //Controlbarwindows

      wndcls.style=0;  //controlbarsdon'thandledoubleclick

      wndcls.lpszClassName=_afxWndControlBar;

      wndcls.hbrBackground=(HBRUSH)(COLOR_BTNFACE+1);

      if(AfxRegisterClass(&wndcls))

          fRegisteredClasses|=AFX_WNDCONTROLBAR_REG;

   }

   if(fToRegister&AFX_WNDMDIFRAME_REG)

   {

      //MDIFramewindow(alsousedforsplitterwindow)

      wndcls.style=CS_DBLCLKS;

      wndcls.hbrBackground=NULL;

      if(_AfxRegisterWithIcon(&wndcls,_afxWndMDIFrame,AFX_IDI_STD_MDIFRAME))

          fRegisteredClasses|=AFX_WNDMDIFRAME_REG;

   }

   if(fToRegister&AFX_WNDFRAMEORVIEW_REG)

   {

      //SDIFrameorMDIChildwindowsorviews-normalcolors

      wndcls.style=CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;

      wndcls.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);

      if(_AfxRegisterWithIcon(&wndcls,_afxWndFrameOrView,AFX_IDI_STD_FRAME))

          fRegisteredClasses|=AFX_WNDFRAMEORVIEW_REG;

   }

   if(fToRegister&AFX_WNDCOMMCTLS_REG)

   {

      //thisflagiscompatiblewiththeoldInitCommonControls()API

      init.dwICC=ICC_WIN95_CLASSES;

      fRegisteredClasses|=_AfxInitCommonControls(&init,AFX_WIN95CTLS_MASK);

      fToRegister&=~AFX_WIN95CTLS_MASK;

   }

   if(fToRegister&AFX_WNDCOMMCTL_UPDOWN_REG)

   {

      init.dwICC=ICC_UPDOWN_CLASS;

      fRegisteredClasses|=_AfxInitCommonControls(&init,AFX_WNDCOMMCTL_UPDOWN_REG);

   }

   if(fToRegister&AFX_WNDCOMMCTL_TREEVIEW_REG)

   {

      init.dwICC=ICC_TREEVIEW_CLASSES;

      fRegisteredClasses|=_AfxInitCommonControls(&init,AFX_WNDCOMMCTL_TREEVIEW_REG);

   }

   if(fToRegister&AFX_WNDCOMMCTL_TAB_REG)

   {

      init.dwICC=ICC_TAB_CLASSES;

      fRegisteredClasses|=_AfxInitCommonControls(&init,AFX_WNDCOMMCTL_TAB_REG);

   }

   if(fToRegister&AFX_WNDCOMMCTL_PROGRESS_REG)

   {

      init.dwICC=ICC_PROGRESS_CLASS;

      fRegisteredClasses|=_AfxInitCommonControls(&init,AFX_WNDCOMMCTL_PROGRESS_REG);

   }

   if(fToRegister&AFX_WNDCOMMCTL_LISTVIEW_REG)

   {

      init.dwICC=ICC_LISTVIEW_CLASSES;

      fRegisteredClasses|=_AfxInitCommonControls(&init,AFX_WNDCOMMCTL_LISTVIEW_REG);

   }

   if(fToRegister&AFX_WNDCOMMCTL_HOTKEY_REG)

   {

      init.dwICC=ICC_HOTKEY_CLASS;

      fRegisteredClasses|=_AfxInitCommonControls(&init,AFX_WNDCOMMCTL_HOTKEY_REG);

   }

   if(fToRegister&AFX_WNDCOMMCTL_BAR_REG)

   {

      init.dwICC=ICC_BAR_CLASSES;

      fRegisteredClasses|=_AfxInitCommonControls(&init,AFX_WNDCOMMCTL_BAR_REG);

   }

   if(fToRegister&AFX_WNDCOMMCTL_ANIMATE_REG)

   {

      init.dwICC=ICC_ANIMATE_CLASS;

      fRegisteredClasses|=_AfxInitCommonControls(&init,AFX_WNDCOMMCTL_ANIMATE_REG);

   }

   if(fToRegister&AFX_WNDCOMMCTL_INTERNET_REG)

   {

      init.dwICC=ICC_INTERNET_CLASSES;

      fRegisteredClasses|=_AfxIn

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1