青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

(轉(zhuǎn))文檔/視圖結(jié)構(gòu)中的各個(gè)部分是如何聯(lián)系到一起的

文檔/視圖結(jié)構(gòu)是MFC中最有特色而又有難度的部分,在這當(dāng)中涉及了應(yīng)用、文檔模板、文檔、視圖、MDI框架窗口、MDI子窗口等不同的對(duì)象,如果不了解 這些部分之間如何關(guān)聯(lián)的話,就可能犯錯(cuò)誤,也就很難編出有水平的文檔/視圖程序。比如我在初學(xué)VC編程的時(shí)候,為應(yīng)用程序添加了兩個(gè)文檔模板,兩個(gè)模板公 用一個(gè)文檔類(lèi),只是視圖不一樣,期望當(dāng)一個(gè)模板的文檔的視圖改變了文檔后,調(diào)用UpdateAllViews后也能更新另一個(gè)文檔模板的視圖,結(jié)果當(dāng)然是 不行的,原因就是對(duì)MFC的文檔/視圖結(jié)構(gòu)沒(méi)有深入的了解,了解的最好方法就是閱讀一下MFC的源代碼。下面就是我的筆記:

(一)應(yīng)用程序?qū)ο笈c文檔模板之間的聯(lián)系:

        首先,在應(yīng)用程序?qū)ο笾杏幸粋€(gè)CDocManager指針類(lèi)型的共有數(shù)據(jù)成員m_pDocManager,在CDocManager中維護(hù)一個(gè) CPtrList類(lèi)型的鏈表:m_tempateList,它是一個(gè)保護(hù)成員。InitInstance函數(shù)中調(diào)用CWinApp:: AddDocTemplate函數(shù),實(shí)際上是調(diào)用m_pDocManager的AddDocTemplate函數(shù)向鏈表m_templateList添加 模板指針。CWinApp提供了GetFirstDocTemplatePosition和GetNextDocTemplate函數(shù)實(shí)現(xiàn)對(duì) m_templateList鏈表的訪問(wèn)(實(shí)際上是調(diào)用了CDocManager的相關(guān)函數(shù))。

         在文件操作方面CWinApp提供的最常用的功能是文件的新建(OnFileNew)和打開(kāi)(OnFileOpen),它也是調(diào)用CDocManager 類(lèi)的同名函數(shù)。對(duì)于新建,一般的時(shí)候在只有一個(gè)文檔模板的時(shí)候,它新建一個(gè)空白的文件;如果有多個(gè)文檔模板的時(shí)候,它會(huì)出現(xiàn)一個(gè)對(duì)話框提示選擇文檔類(lèi)型。 它的源代碼如下:

void CDocManager::OnFileNew()

{

       if (m_templateList.IsEmpty())

       {

                                .......

              return;

       }

                //取第一個(gè)文檔模板的指針

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

       if (m_templateList.GetCount() > 1)

       {

              // 如果多于一個(gè)文檔模板,出現(xiàn)對(duì)話框提示用戶去選擇

              CNewTypeDlg dlg(&m_templateList);

              int nID = dlg.DoModal();

              if (nID == IDOK)

                     pTemplate = dlg.m_pSelectedTemplate;

              else

                     return;     // none - cancel operation

       }

                ......

                //參數(shù)為NULL的時(shí)候OpenDocument File會(huì)新建一個(gè)文件

       pTemplate->OpenDocumentFile(NULL);

}

打開(kāi)文件:

void CDocManager::OnFileOpen()

{

       // 出現(xiàn)打開(kāi)文件對(duì)話框

       CString newName;

       if (!DoPromptFileName(newName, AFX_IDS_OPENFILE,

         OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL))

              return; // open cancelled

       AfxGetApp()->OpenDocumentFile(newName);          //實(shí)際也是調(diào)用文檔模板的同名函數(shù)

}

(二)文檔模板與文檔之間的聯(lián)系:

        從上面看出應(yīng)用程序?qū)ο髮?duì)文件的新建和打開(kāi)是依靠文檔模板的OpenDocumentFile函數(shù)實(shí)現(xiàn)的。MFC的模板類(lèi)是用來(lái)聯(lián)系文檔類(lèi)、視類(lèi)和框架類(lèi)的,在它的構(gòu)造函數(shù)就需要這三者的信息:

CDocTemplate ( UINT nIDResource, CRuntimeClass* pDocClass, CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass );

構(gòu)造函數(shù)利用后三個(gè)參數(shù)為它的三個(gè)CruntimeClass*類(lèi)型的保護(hù)成員賦值:

       m_pDocClass = pDocClass;

       m_pFrameClass = pFrameClass;

       m_pViewClass = pViewClass;

    文檔模板分為單文檔模板和多文檔模板兩種,這兩個(gè)模板的實(shí)現(xiàn)是不同的,除了上面的三個(gè)成員,內(nèi)部有彼此不相同的但是很重要的成員變量。對(duì)于多文檔模板: CPtrList m_docList;,單文檔模板:CDocument* m_pOnlyDoc;。它們都有一個(gè)成員函數(shù)AddDocument,分別各自的成員進(jìn)行賦值操作,而在它們的父類(lèi)的CDocTemplate中則是為 它所添加的文檔的m_pDocTemplate變量賦值為模板自己的地址:

void CDocTemplate::AddDocument(CDocument* pDoc)

{

       ASSERT_VALID(pDoc);

       ASSERT(pDoc->m_pDocTemplate == NULL);  

       pDoc->m_pDocTemplate = this;

}

由于單文檔模板只能擁有一個(gè)文檔,所以它只是維護(hù)一個(gè)指向自己所擁有的模板的指針:m_pOnlyDoc,AddDocument函數(shù)就是要為這個(gè)成員賦值:

void CSingleDocTemplate::AddDocument(CDocument* pDoc)

{

                ......

       CDocTemplate::AddDocument(pDoc);

       m_pOnlyDoc = pDoc;

}
由于多文檔模板可以擁有多個(gè)文檔,所以它要維護(hù)的是包含它所打開(kāi)的所有文檔的指針的鏈表,所以它的AddDocument的實(shí)現(xiàn)為:

void CMultiDocTemplate::AddDocument(CDocument* pDoc)

{

                ......

       CDocTemplate::AddDocument(pDoc);

       m_docList..AddTail(pDoc);

}
    模板通過(guò)m_pOnlyDoc(單文檔)或記住了自己所擁有的所有的模板的指針,并通過(guò)GetFirstDocPosition和GetNextDoc函 數(shù)可以實(shí)現(xiàn)對(duì)它所擁有的文檔的訪問(wèn),同時(shí)使文檔記住了自己所屬文檔模板的指針,同時(shí)文檔提供了GetDocTemplate()函數(shù)可以取得它所屬的模 板。

對(duì)AddDocument函數(shù)的調(diào)用主要是發(fā)生在另一個(gè)成員函數(shù)CreateNewDocument里,它的作用是創(chuàng)建一個(gè)新的文檔:

CDocument* CDocTemplate::CreateNewDocument()

{

       if (m_pDocClass == NULL)

       {

         ……

       }

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

    ……

       AddDocument(pDocument);

       return pDocument;

}

CreateNewDocument函數(shù)主要利用文檔類(lèi)的運(yùn)行時(shí)指針的函數(shù)CreateObject創(chuàng)建一個(gè)新文檔對(duì)象,并利用AddDocument將其指針賦給相關(guān)的成員,留做以后使用。

    在應(yīng)用程序的OnFileNew和OnFileOpen函數(shù)都使用了模板的OpenDocumentFile函數(shù),而且在實(shí)際編程的時(shí)候也大都使用這個(gè)函 數(shù)。在MSDN的文檔說(shuō)這個(gè)函數(shù)當(dāng)參數(shù)不為NULL的時(shí)候打開(kāi)文件,否則就用上面所說(shuō)的CreateNewDocument函數(shù)創(chuàng)建一個(gè)新文檔,那么它是 如何實(shí)現(xiàn)的呢?

CDocument* CSingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,

       BOOL bMakeVisible)

{

       CDocument* pDocument = NULL;

       CFrameWnd* pFrame = NULL;

       BOOL bCreated = FALSE;      // => doc and frame created

       BOOL bWasModified = FALSE;

    //如果已經(jīng)有打開(kāi)的文檔,就會(huì)詢問(wèn)否保存文件

       if (m_pOnlyDoc != NULL)

       {

              pDocument = m_pOnlyDoc;

              if (!pDocument->SaveModified())

                     return NULL;     

              pFrame = (CFrameWnd*)AfxGetMainWnd();

                                ......

       }

    //創(chuàng)建新文件

       else

       {

              pDocument = CreateNewDocument();

              ASSERT(pFrame == NULL);    

              bCreated = TRUE;

       }

                ......

    //如果第一次創(chuàng)建文檔則也要?jiǎng)?chuàng)建框架窗口。

       if (pFrame == NULL)

       {

              ASSERT(bCreated);

              // create frame - set as main document frame

              BOOL bAutoDelete = pDocument->m_bAutoDelete;

              pDocument->m_bAutoDelete = FALSE;

              pFrame = CreateNewFrame(pDocument, NULL);

              pDocument->m_bAutoDelete = bAutoDelete;

                                ......

       }

       if (lpszPathName == NULL)

       {

              // 為新文檔設(shè)置默認(rèn)標(biāo)題

              SetDefaultTitle(pDocument);

        ……

      //一般的時(shí)候重載OnNewDocument初始化一些數(shù)據(jù),如果返回FALSE,表示初始化失//敗,銷(xiāo)毀窗口。

              if (!pDocument->OnNewDocument())

              {

                                                ......

                     if (bCreated)

                            pFrame->DestroyWindow();    // will destroy document

                     return NULL;

              }

       }

       else

       {

              CWaitCursor wait;

              // open an existing document

              bWasModified = pDocument->IsModified();

              pDocument->SetModifiedFlag(FALSE);

              //OnOpenDocument函數(shù)重新初始化文檔對(duì)象

              if (!pDocument->OnOpenDocument(lpszPathName))

              {

                     if (bCreated)

                     {

                //新建文檔的情況

                            pFrame->DestroyWindow();   

                     }

                     else if (!pDocument->IsModified())

                     {

                            // 文檔沒(méi)有被修改,恢復(fù)原來(lái)文檔的修改標(biāo)志

                            pDocument->SetModifiedFlag(bWasModified);

                     }

                     else

                     {

                            // 修改了原始的文檔

                            SetDefaultTitle(pDocument);

                            if (!pDocument->OnNewDocument())

                            {

                                   TRACE0("Error: OnNewDocument failed after trying to open a document - trying to continue.\n");

                            }

                     }

                     return NULL;        // open failed

              }

              pDocument->SetPathName(lpszPathName);

       }

       CWinThread* pThread = AfxGetThread();

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

       {

              pThread->m_pMainWnd = pFrame;

       }

       InitialUpdateFrame(pFrame, pDocument, bMakeVisible);

       return pDocument;

}

以下是多文檔模板的OpenDocumentFile的實(shí)現(xiàn)

CDocument* CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,

       BOOL bMakeVisible)

{

       //新建一個(gè)文檔對(duì)象

       CDocument* pDocument = CreateNewDocument();

……

       BOOL bAutoDelete = pDocument->m_bAutoDelete;

       pDocument->m_bAutoDelete = FALSE;  

       CFrameWnd* pFrame = CreateNewFrame(pDocument, NULL);

       pDocument->m_bAutoDelete = bAutoDelete;

……

       if (lpszPathName == NULL)

    //當(dāng)是新建的時(shí)候

       {

              SetDefaultTitle(pDocument);

              // avoid creating temporary compound file when starting up invisible

              if (!bMakeVisible)

                     pDocument->m_bEmbedded = TRUE;

              if (!pDocument->OnNewDocument())

              {

                     pFrame->DestroyWindow();

                     return NULL;

              }

              m_nUntitledCount++;

       }

       else

       {

              // 打開(kāi)一個(gè)已經(jīng)存在的文件

              CWaitCursor wait;

              if (!pDocument->OnOpenDocument(lpszPathName))

              {

                     // 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;

}

    從上面看出模板類(lèi)的OpenDocumentFile函數(shù)里,利用CreateNewDocument對(duì)象使文檔對(duì)象與模板對(duì)象建立了聯(lián)系,利用了CreateNewFrame函數(shù)使框架窗口與文檔、視圖、模板發(fā)生了聯(lián)系:

posted on 2011-04-17 20:43 蝸牛也Coding 閱讀(502) 評(píng)論(0)  編輯 收藏 引用


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


<2011年4月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

導(dǎo)航

統(tǒng)計(jì)

常用鏈接

留言簿(8)

隨筆檔案(78)

搜索

積分與排名

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲在线不卡| 欧美亚洲一级片| 日韩视频亚洲视频| 亚洲精一区二区三区| 亚洲欧洲日本在线| 日韩一级成人av| 亚洲一区二区三区色| 亚洲欧美日韩第一区 | 久久久久9999亚洲精品| 久久精品人人做人人爽| 久久在线播放| 欧美高清在线一区二区| 亚洲国产精品一区二区第一页| 亚洲国产精品一区二区久| 亚洲九九九在线观看| 亚洲视频你懂的| 欧美一区二区三区视频在线观看 | 免费成人美女女| 欧美日本一区| 国产精品白丝jk黑袜喷水| 国产日韩视频一区二区三区| 国内伊人久久久久久网站视频 | 久久婷婷激情| 亚洲国产日韩欧美| 一区二区日韩伦理片| 亚洲欧美日韩成人| 久久久久一区二区三区四区| 欧美成人四级电影| 国产精品va在线播放| 国产亚洲一级| 日韩一级黄色av| 久久国产一区二区| 91久久精品网| 亚洲欧美日韩系列| 蜜臀久久99精品久久久画质超高清 | 一区二区日本视频| 欧美制服丝袜| 欧美激情免费在线| 国产欧美日韩麻豆91| 亚洲高清在线观看一区| 亚洲影院高清在线| 牛牛国产精品| 亚洲无玛一区| 欧美福利小视频| 国产精品亚洲激情| 日韩一二在线观看| 久久深夜福利免费观看| 亚洲激情在线激情| 新狼窝色av性久久久久久| 欧美激情第1页| 国产综合久久久久久| 一区二区日韩精品| 免费一级欧美在线大片| 亚洲视频在线观看三级| 免费在线观看成人av| 国产农村妇女精品一区二区| 亚洲精品社区| 久热国产精品视频| 亚洲香蕉成视频在线观看 | 欧美一区二区三区在线视频| 亚洲国产精品一区在线观看不卡| 性做久久久久久久免费看| 欧美.com| 尤物精品在线| 久久精品官网| 99这里只有精品| 欧美成人综合在线| 国产在线不卡| 性视频1819p久久| 日韩视频一区二区在线观看| 乱中年女人伦av一区二区| 国产一二精品视频| 午夜国产精品视频| 99精品国产99久久久久久福利| 久久天天躁夜夜躁狠狠躁2022| 国产欧美精品久久| 亚洲自拍偷拍麻豆| 亚洲欧洲视频| 欧美不卡激情三级在线观看| 一区视频在线播放| 久久精品99久久香蕉国产色戒| 在线视频精品| 欧美日韩一卡| 在线亚洲美日韩| 亚洲免费观看高清完整版在线观看熊 | 亚洲国产高清一区二区三区| 久久久久综合网| 亚洲欧美另类中文字幕| 欧美日韩中文字幕日韩欧美| 亚洲理论在线| 亚洲人成艺术| 欧美激情在线狂野欧美精品| 99国内精品久久| 亚洲激情社区| 欧美福利专区| 日韩系列在线| 亚洲伦理精品| 国产精品v日韩精品| 日韩亚洲欧美在线观看| 亚洲人成亚洲人成在线观看| 欧美精品aa| 在线中文字幕日韩| 99在线精品视频| 国产精品久久久久9999| 亚洲欧美日韩在线不卡| 亚洲欧美欧美一区二区三区| 国产伦精品一区二区三区在线观看 | 亚洲午夜精品福利| 夜夜嗨av一区二区三区中文字幕 | 久久精品二区| 久久久久久久久久久久久久一区| 国内精品久久久久久久影视蜜臀 | 久久人人97超碰国产公开结果 | 亚洲美女视频在线免费观看| 亚洲精品国产精品国自产观看浪潮 | 亚洲精品视频免费观看| 亚洲日本中文字幕| 欧美性色aⅴ视频一区日韩精品| 亚洲在线观看免费视频| 亚洲一区精品视频| 国产一区二区三区四区三区四| 玖玖国产精品视频| 欧美成人免费网站| 中国成人在线视频| 亚洲欧美久久| 一区免费观看| 91久久国产精品91久久性色| 欧美色道久久88综合亚洲精品| 亚洲欧美欧美一区二区三区| 欧美一区亚洲| 亚洲日本理论电影| 亚洲视频1区2区| 激情欧美一区二区| 亚洲国产精品高清久久久| 欧美午夜不卡在线观看免费 | 久久精品理论片| 免费黄网站欧美| 亚洲一区二区三区免费观看| 久久精品二区| 日韩亚洲精品视频| 午夜精品www| 亚洲精品乱码视频| 亚洲一品av免费观看| 亚洲高清不卡在线| 一区二区精品国产| 1024精品一区二区三区| 一个人看的www久久| 黄色在线一区| 99视频一区二区| 激情成人综合| 一区二区三区欧美成人| 在线精品观看| 亚洲欧美变态国产另类| 亚洲人人精品| 欧美一区二区视频在线| 一区二区三区久久久| 久久国产欧美日韩精品| 中国成人亚色综合网站| 久久夜色精品国产噜噜av| 亚洲午夜视频| 蜜乳av另类精品一区二区| 欧美影院午夜播放| 欧美日韩免费一区| 蜜桃av一区二区三区| 国产精品久久久久影院色老大 | 国内精品久久久久影院 日本资源| 亚洲精品网站在线播放gif| 国产亚洲视频在线| 亚洲视频一区二区在线观看| 亚洲人成毛片在线播放| 久久www成人_看片免费不卡| 国产精品99久久久久久久女警 | 久久亚洲综合网| 欧美在线看片| 国产精品igao视频网网址不卡日韩| 欧美成人精品一区| 国产亚洲一级| 亚洲一区3d动漫同人无遮挡| 一本一本a久久| 欧美大片18| 欧美黄色aaaa| 亚洲动漫精品| 久久激情中文| 久久久人人人| 国产欧美一区二区精品婷婷| 日韩一二三区视频| 亚洲精品四区| 欧美成人一区二区| 欧美成人一区在线| 伊人成人开心激情综合网| 欧美伊久线香蕉线新在线| 性色av香蕉一区二区| 国产精品免费电影| 99精品欧美| 亚洲最新色图| 欧美日韩一区二区三区在线观看免| 亚洲第一二三四五区| 亚洲人妖在线| 欧美福利在线| 亚洲精品视频在线观看网站|