久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

MFC多文檔和單文檔視結構

 haodafeng_org 2011-01-19

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

//這一頁的代碼最重要了,,呵呵……什么都在這里面呢;


單文檔新建:CWinApp_________docManager->docSingleTemplate的 OpenDocumentFile函數(shù)參數(shù)為空,,此函數(shù)完成了大部分東西,,包括新建文檔類框架類等______________然后是調用CDocument就沒什么意思了,當然我們要是重載了CDocument的新建函數(shù)就是調用子類虛函數(shù),。

多文檔新建:CWinApp_________docManager->docMultTemplate的 OpenDocumentFile函數(shù)參數(shù)為空,,此函數(shù)完成了大部分東西,包括新建文檔類框架類等______________然后是調用CDocument就沒什么意思了,,當然我們要是重載了CDocument的新建函數(shù)就是調用子類虛函數(shù),。

單文檔打開:CWinApp_________docManager中經(jīng)過一個打開對話框傳遞參數(shù),中途還調用了APP的OpenDocumentFile,,當然如果我們的APP重載了這個函數(shù)也要調用我們的但是我們的函數(shù)一定別忘記最后返回是調用父類的此函數(shù)___________docSingleTemplate的 OpenDocumentFile函數(shù)參數(shù)不為空,,此函數(shù)完成了大部分東西,包括新建文檔類框架類等______________然后是調用CDocument就沒什么意思了,,當然我們要是重載了CDocument的新建函數(shù)就是調用子類虛函數(shù),。

多文檔打開:CWinApp_________docManager中經(jīng)過一個打開對話框傳遞參數(shù),中途還調用了APP的OpenDocumentFile,,當然如果我們的APP重載了這個函數(shù)也要調用我們的但是我們的函數(shù)一定別忘記最后返回是調用父類的此函數(shù)___________docMultTemplate的 OpenDocumentFile函數(shù)參數(shù)不為空,,此函數(shù)完成了大部分東西,包括新建文檔類框架類等______________然后是調用CDocument就沒什么意思了,,當然我們要是重載了CDocument的新建函數(shù)就是調用子類虛函數(shù),。

他們兩個只有在docMultTemplate和docSingleTemplate的 OpenDocumentFile函數(shù)中的動作不同,單文檔負責新建框架類和視類但是如果存在了我們就不重建了,,只是給其賦值,。而多文檔無論如何都會新建一個視類和框架類文檔類,這也就是為什么他是多文檔結構的原因,。

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
接下來介紹這個最重要的函數(shù),,它基本什么都干了,,不管是新建還是打開都得調用它,,呵呵……

//
CDocument* CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,
 BOOL bMakeVisible)
{
 //下面調用的是CDocTemplate::CreateNewDocument()
 CDocument* pDocument = CreateNewDocument();//這里面調用了AddDocument(pDocument);
                                            //添加了一個CMyMultiTestDoc : public CDocument
                                                   //CMultiDocTemplate::m_docList保存的所有該種文檔的  
                                                   //文檔實例的指針列表。
 if (pDocument == NULL)
 {
  TRACE0("CDocTemplate::CreateNewDocument returned NULL.\n");
  AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
  return NULL;
 }
 ASSERT_VALID(pDocument);

 BOOL bAutoDelete = pDocument->m_bAutoDelete;
 pDocument->m_bAutoDelete = FALSE;   // don't destroy if something goes wrong
 CFrameWnd* pFrame = CreateNewFrame(pDocument, NULL);//創(chuàng)建了一個新的CChildFrame框架
 pDocument->m_bAutoDelete = bAutoDelete;
 if (pFrame == NULL)
 {
  AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
  delete pDocument;       // explicit delete on error
  return NULL;
 }
 ASSERT_VALID(pFrame);

 if (lpszPathName == NULL)
 {
  // create a new document - with default document name
  SetDefaultTitle(pDocument);

  // avoid creating temporary compound file when starting up invisible
  if (!bMakeVisible)
   pDocument->m_bEmbedded = TRUE;

  if (!pDocument->OnNewDocument())//剛打開時新建的文檔,。add  by ralf
  {
   // user has be alerted to what failed in OnNewDocument
   TRACE0("CDocument::OnNewDocument returned FALSE.\n");
   pFrame->DestroyWindow();
   return NULL;
  }

  // it worked, now bump untitled count
  m_nUntitledCount++;
 }
 else
 {
  // open an existing document
  CWaitCursor wait;
  if (!pDocument->OnOpenDocument(lpszPathName))//這里是打開一個文檔,。add  by ralf
  {
   // user has be alerted to what failed in OnOpenDocument
   TRACE0("CDocument::OnOpenDocument returned FALSE.\n");
   pFrame->DestroyWindow();
   return NULL;
  }
  pDocument->SetPathName(lpszPathName);
 }

 InitialUpdateFrame(pFrame, pDocument, bMakeVisible);
 return pDocument;
}
要了解   文檔、視圖、框架窗口,、文檔模板之間的相互關系,關鍵要理解他們的結構  
   
  1,、首先應該對   CWinApp類有充分的了解  
          它包含并管理著應用程序的文檔/視窗的所有信息。它有一個成員變量    
          CDocManager   *   m_pDocManager,,此變量是文檔/視窗的管理器,,m_templateList  
          是CDocManager里的一個列表,此列表里保存了所有文檔模板的指針,,當用戶調用  
          CWinApp::AddDocTemplate(   pDocTemplate   )   后該pDocTemplate存入了  
          CWinApp::m_pDocManager::m_templateList里,。  
          CWinApp::GetFirstDocTemplatePosition()  
          CWinApp::GetNextDocTemplate(POSITION&   pos)  
          是遍例所有的文檔模板指針。  
   
  2,、上面我們提到了文檔模板(CMultiDocTemplate(我們主要針對對文檔)),  
          這是一個極重要的類,。CMultiDocTemplate::m_docList保存的所有該種文檔的  
          文檔實例的指針列表。下面兩個函數(shù)用于維護CMultiDocTemplate::m_docList數(shù)據(jù)  
          CMultiDocTemplate::AddDocument(CDocument*   pDoc);  
          CMultiDocTemplate::RemoveDocument(CDocument*   pDoc);  
          而CMultiDocTemplate::GetFirstDocPosition()   const;  
          CMultiDocTemplate::CDocument*   GetNextDoc(POSITION&   rPos)   const;  
          用于遍例該文檔類型所有文檔實例,。  
   
  3,、上面提到文檔(CDocument)  
        CDocument   我們最熟悉不過了。每一個文檔實例可有多個視與之相對應,。  
        CDocument::m_viewList用來保存所有與此文檔實例相關的View 
★★★★這里我拉魯夫說一下:CDocument::AddView函數(shù)用來維護m_viewList數(shù)據(jù)但我們一般不用★★★★
        void CDocument::AddView(CView* pView)//★★★MFC源碼
       {
     ASSERT_VALID(pView);
     ASSERT(pView->m_pDocument == NULL); // must not be already attached
     ASSERT(m_viewList.Find(pView, NULL) == NULL);   // must not be in list

            m_viewList.AddTail(pView);
     ASSERT(pView->m_pDocument == NULL); // must be un-attached
     pView->m_pDocument = this;

     OnChangedViewList();    // must be the last thing done to the document
       }
        CDocument::GetDocTemplate   可獲得CMultiDocTemplate;  
  4,、CView   他是放在CMDIChildWnd里的,每一個CMDIChildWnd有一個View  
        CView::GetDocument可獲得與此視相關的CDocument  
        CView::GetParentFrame()   可獲得CMDIChildWnd;  
   
  通過以上分析可見CWinApp,CMDIChildWnd,CView,CDocument,CMultiDocTemplate之間知道其中一個實例  
  必可知道其他所有幾個實例,CWinApp統(tǒng)領全局,,任何時候,,只要獲得CWinApp實例,則所有的文檔模板,,  
  文檔實例,,視,F(xiàn)rame窗口均可被枚舉出來,。AfxGetApp()   獲得CWinApp實例指針,。
★★★★★最后我介紹一個最重要的:其實我們一個文檔一般就對應一個視圖!!!!!!!★★★★

——————————————————————————————————————————


 



獲得CWinApp

獲得CMainFrame

獲得CChildFrame

獲得CDocument

獲得CView

在CWinApp中

AfxGetMainWnd()

m_pMainWnd

AfxGetMainWnd()->MDIGetActive()

AfxGetMainWnd()->GetActiveFrame()

SDI:AfxGetMainWnd()->GetActiveView()->GetDocument()

MDI:AfxGetMainWnd()->MDIGetActive()->GetActiveView()->GetDocument()

SDI:AfxGetMainWnd()->GetActiveView()  
MDI:AfxGetMainWnd()->MDIGetActive()->GetActiveView()
在CMainFrame中

AfxGetApp()

theApp


MDIGetActive()

GetActiveFrame()

SDI:GetActiveView()->GetDocument()  
MDI:MDIGetActive()->GetActiveView()->GetDocument()  
SDI:GetActiveView()  
MDI:MDIGetActive()->GetActiveView()
在CChildFrame中

AfxGetApp()

theApp

GetParentFrame()
GetActiveView()->GetDocument()   GetActiveView()
在CDocument中

AfxGetApp()

theApp

AfxGetMainWnd()  

AfxGetMainWnd()->MDIGetActive()

AfxGetMainWnd()->GetActiveFrame()


POSITION   pos   =   GetFirstViewPosition();GetNextView(pos)  
在CView中

AfxGetApp()

theApp

AfxGetMainWnd()   GetParentFrame()   GetDocument()
在其他類中

AfxGetApp()

AfxGetMainWnd()  

AfxGetMainWnd()->MDIGetActive()

AfxGetMainWnd()->GetActiveFrame()

SDI:AfxGetMainWnd()->GetActiveView()->GetDocument()

MDI:AfxGetMainWnd()->MDIGetActive()->GetActiveView()->GetDocument()

SDI:AfxGetMainWnd()->GetActiveView()  
MDI:AfxGetMainWnd()->MDIGetActive()->GetActiveView()

理一理MFC的這幾個類的關系,可以很容易明白上面的這些亂七八糟的邏輯,。
App是應用域,,所有的域中的東西都可以通過全局函數(shù)訪問到它。
MainFrame是主框架,,也基本可以用全局函數(shù)訪問到,。
MainFrame下是若干個ChildFrame,ChildFrame中若干個View和Document(可能不成對),,ChildFrame管理著View,,View和Document進行互操作。
因此整體框架就出來了,,一般除了直接應用的關系都可以通過MainFrame-->Active ChildFrame-->Active View-->Document這條線進行訪問
_______________________________

關于MFC下的文檔和視圖以及框架之間的訪問, 這些問題已經(jīng)是老生常談了,但我覺得還是都沒有詳細的說明,特

別是對于英語較差的人,我查看了一些blog,總結了一下!希望對和我一樣的人有點幫助!
一:
      1:   因為對于SDI程序,,主框架窗口就是文檔框窗(如果這個也不知道,就要查看一下MFC下的單文檔的構成原理了).
          下面所說的是關于單文檔的.          
         
        例子: 在CMainFrame框架中如何得到視圖類的指針.
                    可以 先得到框架指針,然后調用 GetActiveView 函數(shù)指向當前活動視.
C **View * pView;
                 pView=(C**View*)((CFrameWnd*)AfxGetApp()->m_pMainWnd)->GetActiveView();

          當然這些也許都知道是這么用的,但真正的m_pMainWnd和AfxGetApp()是什么意思也許有的人不明白.
         大家也許都知道如何在App中獲得MainFrame指針(框架類): CWinApp 中的 m_pMainWnd變量就是CMainFrame的指針.

   所以在別的類下也可以先得到m_pMainWnd,就得到了MainFrame的指針. 所以得到視圖類的指針,必先 得到CFrameWnd的指針m_pMainWnd,然后在調用FrameWnd下的GetActiveView 就指向當前活動視.
m_pMainWnd的由來:
      每一個MFC應用程序都有一個CWinApp派生類的對象,。這個對象對應著程序的主線程。而 CWinApp 類中有一個 CWnd * m_pMainWnd 成員變量,。這個成員變量記錄了應用程序的主窗口,。
當你新建一個MFC應用程序的時候,在 InitInstance虛函數(shù)里都會出現(xiàn)對 m_pMainWnd 賦值的語句.唯一的例外是單文檔界面的MFC應用程序,,你無法在 InitInstance 函數(shù)里看到這段代碼,,因為它已經(jīng)被隱藏在 ProcessShellCommand 這個函數(shù)里了。由此你就可以下結論了:只要創(chuàng)建自己的窗口類,,就要把這個類的對象賦值給 m_pMainWnd .而這個成員只能在C**APP類中才可以使用,所以怎樣使用這個CWinApp類里的CWnd 類型的變量來得到主框架窗口的指針呢??
AfxGetApp函數(shù)才可以 , 因為AfxGetApp()得到的是CWinApp類的對象,且AfxGetApp返回值為CWinApp對象指針,,就是MFC生成的C**App.cpp中定義的那個對象(對象theApp的指針)。
因為你是在自己創(chuàng)建的項目中得到CWndApp成員函數(shù)或者成員變量,所以你必須強制轉換為你自己的項目中的類,,才能找到成員函數(shù)或者變量.
注: 在單文檔中,獲得視指針的最簡單的方法還是
((C**View *)CFrameWnd::GetActiveView())
             
          2:     當然在FrameWnd中也可以得到文檔類的指針:
                       CMyDocument* pDoc;
                       pDoc=(CMyDocument*)((CFrameWnd*)AfxGetApp()->m_pMainWnd)->GetActiveDocument();
        
          3:     由上面可以知道:在View中怎樣獲得MainFrame指針
CMainFrame *pMain=(CMainFrame *)AfxGetApp()->m_pMainWnd;

注: 從視圖類中獲得主幀窗口類指針:用函數(shù):CWnd::GetParentFrame()或AfxGetMainWnd()也
可達到目的,。GetParentFrame()的工作原理是在父窗口鏈中搜索,直到找到CFrameWnd或其派生類為止,,并返回其指針,。

((CMainFrame *)CWnd::GetParentFrame())
或者
((CMainFrame *)AfxGetMainWnd())
        
二:
當然對于MDI程序,由于子窗口才是文檔框窗,,因此首先要用GetActiveFrame()取得活動子框架窗口,,然后通過該子窗口獲取活動視圖和文檔:

                 CMDIChildWnd* pChild=(CMDIChildWnd*)((CFrameWnd*)AfxGetApp()->m_pMainWnd)-            

        >GetActiveFrame();
取得活動視圖:
CMyView* pView=(CMyView*)pChild->GetActiveView();

取得活動文檔:
CMyDocument* pDoc=pChild->GetActiveDocument();


注: 也可以用這種方法來得到多文檔中的視指針
//獲得活動子框架窗口
CMDIChildWnd* pChild=(CMDIChildWnd*)GetActiveFrame();
//或:
CMDIChildWnd* pChild=MDIGetActive();
//獲得活動子幀窗口的活動視圖
CMyView* pView=(CMyView*)pChild->GetActiveView();


三:
1.   從視圖類獲得文檔類的指針
            在視圖類中需要引用文檔類的地方之前,使用以下語句:
C*Doc *pDoc=(C*Doc*)GetDocument();
以后便可使用pDoc指針訪問文檔類,。
2.    從文檔類取得視圖類的指針 CDocument類提供了兩個函數(shù)用于視圖類的定位:

   GetFirstViewPosition()和GetNextView()

注意:GetNextView()括號中的參數(shù)用的是引用方式,,因此執(zhí)行后值可能改變.GetFirstViewPosition()用于

返 回第一個視圖位置(返回的并非視圖類指針,而是一個POSITION類型值),,GetNextView()有兩個功能:返回下一個視圖類的指針以及用引用 調動的方式來改變傳入的POSITION類型參數(shù)的值,。很明顯,在Test程序中,,只有一個視圖類,,因此只需將這兩個函數(shù)調用一次即可得到 CTestView的指針如下(需定義一個POSITION結構變量來輔助操作):

    C*View* pView;
POSITION pos=GetFirstViewPosition();
pView=GetNextView(pos);

這 樣,便可到了C*View類的指針pView.執(zhí)行完成幾句后,,變量pos=NULL,因為沒有下一個視圖類,,自然也沒有下一個視圖類的 POSITION.但是之幾條語句太簡單,不具有太強的通用性和安全特征,;當象前面說的那樣,,當要在多個視圖為中返回某個指定類的指針時,我們需要遍歷所 有視圖類,,直到找到指定類為止,。判斷一個類指針指向的是否某個類的實例時,可用IsKindOf()成員函數(shù)時行檢查.

如:
pView->IsKindOf(RUNTIME_CLASS(C*View));
即可檢查pView所指是否是C*View類,。
有了以上基礎,,我們已經(jīng)可以從文檔類取得任何類的指針。為了方便,,我們將其作為一個文檔類的成員函數(shù),,它有一個參數(shù),表示要獲得哪個類的指針,。實現(xiàn)如下:
          CView* C*Doc::GetVieww(CRuntimeClass* pClass)
{ CView* pView;
POSITION pos=GetFirstViewPosition();
while(pos!=NULL){
pView=GetNextView(pos);
if(!pView->IsKindOf(pClass))
break;}
if(!pView->IsKindOf(pClass)){
AfxMessageBox("Connt Locate the View.");
return NULL;}
return pView;}
其中用了兩次視圖類的成員函數(shù)IsKindOf()來判斷,,是因為退出while循環(huán)有三種可能:
1.pos為NULL,即已經(jīng)不存在下一個視圖類供操作,;
2.pView已符合要求,。
3.1 和2同是滿足。這是因為GetNextView()的功能是將當前視圖指針改變成一個視圖的位置同時返回當前視圖指針,,因此pos是pView的下一個視圖類的POSITION,完全有可能既是pos==NULL又是pView符合需要,。當所需的視圖是最后一個視圖是最后一個視圖類時就如引。因此需采用兩次判斷,。
使用該函數(shù)應遵循如下格式(以取得CTestView指針為例):
CTestView* pTestView=(CTestView*)GetView(RUNTIME_CLASS(CTestView));
RUNTIME_CLASS是一個宏,,可以簡單地理解它的作用:將類的名字轉化為CRuntimeClass為指針。
至于強制類型轉換也是為了安全特性考慮的,,因為從同一個基類之間的指針類型是互相兼容的,。這種強制類型轉換也許并不必

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報,。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多