初学者分析MFC代码7

作者:liguisen

bloghttp://blog.csdn.net/liguisen/

 

在这一篇我们准备进入MFC源码分析,打开上一篇所建立的工程,不加任何断点,F11开始调试,进入APPMODUL.CPP

extern "C" int WINAPI

_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

         LPTSTR lpCmdLine, int nCmdShow)

{//zuilang光标停在这里,注意,加个断点。

         // call shared/exported WinMain

         return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

}

然后停止debug,在CSdiApp theApp;这一句加上断点,重新F11开始,你会发现,光标首先停在这一句而不是刚才的那一句,这说明了“在C++程序中,全局对象在主程序被执行之前就已经被构造好了”(visual c++ .net技术内幕第六版P23)。

下面不断继续F11

CSdiApp::CSdiApp()//zuilangSdi.cpp

{// zuilang光标停在这里。        

}

CWinApp::CWinApp(LPCTSTR lpszAppName) //zuilangAPPCORE.CPP

{// zuilang:光标停在这里,theApp父类是CWinApp

                  if (lpszAppName != NULL)

                    m_pszAppName = _tcsdup(lpszAppName);

           ……

}

CWinThread::CWinThread()//zuilangTHRDCORE.CPP

{// zuilang光标停在这里,CwinApp父类是CWinThread

           m_pThreadParams = NULL;

……

}

CCmdTarget::CCmdTarget()//zuilangCMDTARG.CPP

{// zuilang光标停在这里,CWinThread父类是CCmdTarget

……

}

_ AFX_INLINE CObject::CObject()//zuilangAFX.INL

  {// zuilang光标停在这里,CCmdTarget父类是:CObject }

至此,F5

extern "C" int WINAPI

_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

                  LPTSTR lpCmdLine, int nCmdShow)

{// zuilang光标停在这里,改为F11往下。

                  // call shared/exported WinMain

                  return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

}

 

int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

         LPTSTR lpCmdLine, int nCmdShow)

{// zuilang光标停在这里,F10往下。

         ASSERT(hPrevInstance == NULL);

 

         int nReturnCode = -1;

         CWinThread* pThread = AfxGetThread();

         CWinApp* pApp = AfxGetApp();

 

         // AFX internal initialization

         if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))

                   goto InitFailure;

 

         // App global initializations (rare)

         if (pApp != NULL && !pApp->InitApplication())

                   goto InitFailure;

 

         // Perform specific initializations

         if (!pThread->InitInstance())//zuilang光标停在这里,F11回到CSdiApp::InitInstance()

         {

                   if (pThread->m_pMainWnd != NULL)

                   {

                            TRACE0("Warning: Destroying non-NULL m_pMainWnd/n");

                            pThread->m_pMainWnd->DestroyWindow();

                   }

                  nReturnCode = pThread->ExitInstance();

                   goto InitFailure;

         }

         nReturnCode = pThread->Run();

 

InitFailure:

#ifdef _DEBUG

         // Check for missing AfxLockTempMap calls

         if (AfxGetModuleThreadState()->m_nTempMapLock != 0)

         {

                  TRACE1("Warning: Temp map lock count non-zero (%ld)./n",

                            AfxGetModuleThreadState()->m_nTempMapLock);

         }

         AfxLockTempMaps();

         AfxUnlockTempMaps(-1);

#endif

 

         AfxWinTerm();

         return nReturnCode;

}

 

BOOL CSdiApp::InitInstance()

{// zuilang光标停在这里,F10往下。下面是单文档模板的创建,暂时忽略。

         CSingleDocTemplate* pDocTemplate;

         pDocTemplate = new CSingleDocTemplate(

                  IDR_MAINFRAME,

                  RUNTIME_CLASS(CSdiDoc),

                  RUNTIME_CLASS(CMainFrame),      

                  RUNTIME_CLASS(CSdiView));

         AddDocTemplate(pDocTemplate);

        

         CCommandLineInfo cmdInfo;

         ParseCommandLine(cmdInfo);

         // zuilang处理命令行、外壳命令等

         if (!ProcessShellCommand(cmdInfo)) // zuilang光标停在这里,F11.

                   return FALSE;

        

         m_pMainWnd->ShowWindow(SW_SHOW);

         m_pMainWnd->UpdateWindow();

 

         return TRUE;

}

 

BOOL CWinApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo)

{// zuilang光标停在这里,F10往下。

         BOOL bResult = TRUE;

         switch (rCmdInfo.m_nShellCommand)

         {

         case CCommandLineInfo::FileNew:

                   if (!AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL)) // zuilang光标停在这里,F11往下,然后马上Shift+F11跳出AfxGetApp()然后再次F11进入OnCmdMsgMFC越来越复杂^_^

                            OnFileNew();

                   if (m_pMainWnd == NULL)

                            bResult = FALSE;

                   break;

……

}

OnCmdMsg函数较长,只贴最后我们关心的:

BOOL CCmdTarget::OnCmdMsg(UINT nID, int nCode, void* pExtra,

         AFX_CMDHANDLERINFO* pHandlerInfo)

{// zuilang光标停在这里,找下面那一句。

……………..

#endif //_DEBUG

                            return _AfxDispatchCmdMsg(this, nID, nCode,

                                    lpEntry->pfn, pExtra, lpEntry->nSig, pHandlerInfo);// zuilang:找到这一句,CTRL+F10运行到这里,F11继续。

                   }

         }

         return FALSE;   // not handled

}

 

AFX_STATIC BOOL AFXAPI _AfxDispatchCmdMsg(CCmdTarget* pTarget, UINT nID, int nCode,

         AFX_PMSG pfn, void* pExtra, UINT nSig, AFX_CMDHANDLERINFO* pHandlerInfo)

                   // return TRUE to stop routing

{// zuilang光标停在这里,找下面那一句。

……………..

switch (nSig)

         {

         case AfxSig_vv:

                   // normal command or control notification

                  ASSERT(CN_COMMAND == 0);        // CN_COMMAND same as BN_CLICKED

                  ASSERT(pExtra == NULL);

                  (pTarget->*mmf.pfn_COMMAND)(); // zuilang找到这一句,CTRL+F10运行到这里,F11继续。

                   break;

……………..

}

 

void CWinApp::OnFileNew()

{ // zuilang终于找到FileNew

         if (m_pDocManager != NULL)

                  m_pDocManager->OnFileNew();//zuilang到这里F11

}

 

void CDocManager::OnFileNew()

{// zuilang光标停在这里,找下面那一句。

         if (m_templateList.IsEmpty())

         {

                  TRACE0("Error: no document templates registered with CWinApp./n");

                  AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);

                   return;

         }

 

         CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetHead();

         if (m_templateList.GetCount() > 1)

         {

                   // more than one document template to choose from

                   // bring up dialog prompting user

                  CNewTypeDlg dlg(&m_templateList);

                   int nID = dlg.DoModal();

                   if (nID == IDOK)

                            pTemplate = dlg.m_pSelectedTemplate;

                   else

                            return;     // none - cancel operation

         }

 

         ASSERT(pTemplate != NULL);

         ASSERT_KINDOF(CDocTemplate, pTemplate);

 

         pTemplate->OpenDocumentFile(NULL); // zuilangCTRL+F10到这里F11

                   // if returns NULL, the user has already been alerted

}

CDocument* CSingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,

         BOOL bMakeVisible)

         // if lpszPathName == NULL => create new file of this type

{// zuilang光标停在这里,找下面那一句。

……………..

         InitialUpdateFrame(pFrame, pDocument, bMakeVisible); // zuilangCTRL+F10到这里F11

 

         return pDocument;

}

 

 

至此我突然想改变主意,不再继续往下分析,原因有:

A:方法已经很明显,再往下,显得太罗嗦。

B:最困难的不是里面的知识点,而是要把它们很简单的说出来。很简单的说出来,让人很容易明白,这正是我的初衷,现在已不太可能。

同时,也放弃一开始说的逐句代码添加回去直到和删除代码前一模一样,以便分析每一行代码的作用的想法,因为我觉得到了现在已经不是一件什么难事。

下面用另外一个方法结尾,新建一个SDI工程(用一开始备份的也行),利用ClassWizardCMainFrame添加如下函数:

1,   BOOL CMainFrame::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)

2,   nt CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

3,   BOOL CMainFrame::DestroyWindow()

4,   void CMainFrame::OnDestroy()

5,   BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)

CSdiApp添加如下函数:

1,   BOOL CSdiApp::InitApplication()

2,   int CSdiApp::ExitInstance()

 

CsdiView添加如下函数:

1,   BOOL CSdiView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)

2,   void CSdiView::OnInitialUpdate()

3,   BOOL CSdiView::DestroyWindow()

4,   int CSdiView::OnCreate(LPCREATESTRUCT lpCreateStruct)

5,   void CSdiView::OnDestroy()

 

         通过增加上述函数(其实就是重载,放到自己的代码里,看得更清楚),然后再用“断点法”,你也许更容易发现MFC的一般流程。

 

 

初学者分析MFC代码,END!!!

 

你可能感兴趣的:(初学者分析MFC代码7)