MFC單文檔內部執行過程

第一步:

調試過程中發現,在CSingleDocTemplate的構造函數中初始化了CSingleDocTemplate成員變量m_pOnlyDoc = NULL;

並調用父類CDocTemplate的構造函數,在父類的構造函數中初始化了三個成員變量:

CRuntimeClass*m_pDocClass =RUNTIME_CALSS(CSdiDoc);      

CRuntimeClass*m_pFrameClass = RUNTIME_CALSS(CSdiFrm);

CRuntimeClass*m_pViewClass = RUNTIME_CALSS(CSdiView);

第二步:

調用CWinApp的AddDocTemplate,進入函數內部:

實參是:pDocTemp(CSingleDocTemplate)。

CWinApp中有一個m_pDocManager(CDocManager)的指針

CWinApp::AddDocTemplate函數內部實例化了m_pDocManager

並調用m_pDocManagerCDocManager::AddDocTemplate函數。

下面是該函數的內部實現過程(省略次要部分):

實參:pDocTemp(CSingleDocTemplate)

void  CDocManager::AddDocTemplate(CDocTemplate* pTemplate)

{

     if(…)

      {…}

     else

    {

       …

       pTemplate->LoadTemplate();//內部執行可以不用關心

      m_templateList.AddTail(pTemplate);

    } 

}

 

//CDocManager中有一個成員:m_templateList

m_templateList.AddTail(pTemplate);//內部實現過程:

使用尾插法將pTemplate插入到m_templateList鏈表的尾部。

第三步:

OnFileNew();函數的內部實現過程:

 

void CWinApp::OnFileNew()

{

//m_pDocManager在第二步CWinApp::AddDocTemplate中已經實例化了

if (m_pDocManager != NULL)

m_pDocManager->OnFileNew();

}

補充:m_pDocManager成員函數:OnFileNew()

AddDocTemplate(CDocTemplate* pTemplate)

m_pDocManager->OnFileNew()//內部實現過程:

void CDocManager::OnFileNew()

{

      //CDocManager::AddDocTemplate中添加了一個單文檔模板到m_templateList的尾部,所以此處不爲空

      if (m_templateList.IsEmpty())

      {…     }

     //獲取模板鏈表的第一個元素,此時拿到的是我們之前添加的單文檔模板

    //如果有多個模板,會彈出對話框,讓用戶選擇

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

     if (m_templateList.GetCount() > 1)

      {

           CNewTypeDlg dlg(&m_templateList);

           int nID = dlg.DoModal();

           if (nID == IDOK)

                 pTemplate = dlg.m_pSelectedTemplate;

           else

                 return;    

      }

      //pTemplate是我們之前添加的單文檔模板,創建frame,創建文檔

      pTemplate->OpenDocumentFile(NULL);

}

pTemplate->OpenDocumentFile(NULL);//內部實現過程:

CDocument    *CSingleDocTemplate::OpenDocumentFile(

LPCTSTR lpszPathName, BOOL bMakeVisible)

{

      CDocument* pDocument = NULL;

      CFrameWnd* pFrame = NULL;

//此時m_pOnlyDocCSingleDocTemplate)依舊爲空

if (m_pOnlyDoc != NULL)

      {….    }

else

 {

//父類的成員函數,創建新文檔,給m_pOnlyDoc賦值

 pDocument = CreateNewDocument();

}

ASSERT(pDocument == m_pOnlyDoc);//成功調用上面的函數,兩者必然相等

if (pFrame == NULL)

 {

  pFrame = CreateNewFrame(pDocument, NULL);

}

      CWinThread* pThread = AfxGetThread();//主線程

      if (bCreated && pThread->m_pMainWnd == NULL)

      {

                 pThread->m_pMainWnd = pFrame;//設置主窗口

      }

      InitialUpdateFrame(pFrame, pDocument, bMakeVisible);

// InitialUpdateFrame內部實現過程:

pFrame->InitialUpdateFrame(pDoc, bMakeVisible);

      return pDocument;//返回創建的pDocument

}// OpenDocumentFile函數結尾


 

pDocument = CreateNewDocument();//內部實現過程:

CDocument* CDocTemplate::CreateNewDocument()

{

CDocument   *pDocument =(CDocument*)m_pDocClass->CreateObject();

//m_pDocClassRUNTIME_CLASSCSdiDoc),

//在初始化CSingleDocTemplate傳進來的參數。補充:m_pDocClass是文檔模板類(CDocTemplate)的成員變量

AddDocument(pDocument);//CSingleDocTemplate的成員函數

return pDocument;

}

 

AddDocument(pDocument);//內部實現過程:

void CSingleDocTemplate::AddDocument(CDocument* pDoc)

{

      CDocTemplate::AddDocument(pDoc);//調用父類的

      m_pOnlyDoc = pDoc;//將剛創建的文檔對象賦值給CSingleDocTemplate的成員變量。終於在這裏賦值了!

}

 

pFrame = CreateNewFrame(pDocument, NULL);//內部實現過程

CFrameWnd* CDocTemplate::CreateNewFrame(CDocument* pDoc, CFrameWnd* pOther)

{

CCreateContext context;

context.m_pCurrentFrame = pOther;//pOther=NULL

context.m_pCurrentDoc = pDoc;//傳進來的實參

context.m_pNewViewClass=m_pViewClass;

//RUNTIME_CALSS(CSdiView)

context.m_pNewDocTemplate = this;

//this:CSingDocTemplate

CFrameWnd*pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();

if (!pFrame->LoadFrame(m_nIDResource,

                                     WS_OVERLAPPEDWINDOW|FWS_ADDTOTITLE,  

                                     NULL, &context)

 )

 {…..}

return pFrame;//返回創建好的frame

}

 

最後一步:

小結:

CWinApp中有一個m_pDocManager指針,m_pDocManager有一個成員變量m_templateList,維護了一個模板鏈表。CSingleDocTemplate中有一個m_pOnlyDoc,維護了一個文檔指針。

CWinApp的父類CWinThread中有一個m_pMainWnd指針,維護了Frame窗口。

CFrameWnd中有一個SetActiveView(),維護了View

CView中有一個CDocument*m_pDocument,保存了文檔指針。

CDocument中有一個m_viewList維護了一個視圖鏈表。             

 


 

 

 


 

 


 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章