多模板文件檢視結構的應用 (轉)
FMD STUDIO 之 VC++ 之 技術篇 之 : 【script: history.back()">回上一頁】 編號 主 題 來 源收錄時間 5 多模板文件檢視結構的應用 自撰 00.05.08
多模板文件檢視結構的應用
一、概述
①在一個MDI中,需要使用到不同型別的子視窗,而每種型別視窗有可能有很多個,對應不同的資料。
這時,可以使用多模板的文件檢視結構。以利用文件檢視結構帶來的便利。
②建立某種型別的MDI子視窗時,對應文件模板的OpenDocumentFile()
而其引數LPCTSTR lpszFileName可以作為建立MDI視窗時的引數
③在使用過程中,文件不一定要對應,而是根據需要定義成內部的資料結構。
但MFC文件結構中,很多地方與實際檔案相聯絡,因此,使用中,有些細節需處理。
二、多文件文件模板的建立
①在應用程式類中建立多個文件模板指標作為成員資料
例:
CMultiDocTemplate * pCalcDocTemplate;
CMultiDocTemplate * pDataDocTemplate;
②在應用程式類InitInstance中建立多個文件模板物件。
每種文件模板對應不同的文件、檢視類組合。
例:
pCalcDocTemplate = new CMultiDocTemplate( IDR_VFPTYPE, RUNTIME_CLASS(CVFPDoc), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(CVFPView)); AddDocTemplate(pCalcDocTemplate); pDataDocTemplate = new CMultiDocTemplate( IDR_DATATYPE, RUNTIME_CLASS(CDataDoc), RUNTIME_CLASS(CDataChildFrame), // custom MDI child frame RUNTIME_CLASS(CDataListView)); AddDocTemplate(pDataDocTemplate);
③在應用程式類中新增建立視窗的成員。
例:
CDocument * CXXXApp::OpenDataDocumentFile(LPCTSTR lpszFileName) { if(pDataDocTemplate) return pDataDocTemplate-> OpenDocumentFile(lpszFileName); else return NULL; } CDocument * CXXXApp::OpenCalcDocumentFile(LPCTSTR lpszFileName) { if(pCalcDocTemplate) return pCalcDocTemplate-> OpenDocumentFile(lpszFileName); else return NULL; }
④需要建立不同型別的MDI子視窗時,呼叫以上成員即可
三、細節處理
①避免同一引數對應的MDI子視窗多次開啟。
在處理磁碟檔案時,開啟某一檔案時,文件管理器會檢查是否開啟過,開啟過,則啟用已經開啟的視窗。
當自己呼叫文件模板的OpenDocumentFile開啟時,這一檢查被繞過了。
但需要時,可以在自己的開啟"檔案"成員中新增相應程式碼(基本上是MFC原碼的複製)。
例:以上的OpenCalcDocumentFile可更改為:
CDocument * CXXXApp::OpenCalcDocumentFile(LPCTSTR lpszFileName) { if(pCalcDocTemplate) { CDocument* pOpenDocument = NULL; pCalcDocTemplate-> MatchDocType(lpszFileName, pOpenDocument); //判斷是否lpszFileName的視窗已經建立 if (pOpenDocument != NULL) //若已經建立過,則啟用 { POSITION p= pOpenDocument-> GetFirstViewPosition(); if (pos != NULL) { CView* pView = pOpenDocument-> GetNextView(pos); // get first one ASSERT_VALID(pView); CFrameWnd* pFrame = pView-> GetParentFrame(); if (pFrame != NULL) pFrame-> ActivateFrame(); else TRACE0("Error: Can not find a frame for document to activate.n"); CFrameWnd* pAppFrame; if (pFrame != (pAppFrame = (CFrameWnd*)AfxGetApp()-> m_pMainWnd)) { ASSERT_KINDOF(CFrameWnd, pAppFrame); pAppFrame-> ActivateFrame(); } } else { TRACE0("Error: Can not find a view for document to activate.n"); } return pOpenDocument; } else //否則直接開啟 return pCalcDocTemplate-> OpenDocumentFile(lpszFileName); } else return NULL; }
但改寫後,發現某些情況下視窗還是被重複開啟。原因是MatchDocType判斷失誤。
在MatchDocType中,需要比較文件物件中儲存的檔名和輸入的文件名引數。
但文件物件建立時,會對文件名取全路徑,而以上作為引數的"檔名"被認為是相對路徑而新增了目錄名。比較時自然不相等了。
好在MFC在設計時已經考慮了這些,文件類提供了虛擬函式SetPathName(LPCTSTR lpszPathName, BOOL bAddToMRU),
在自己的文件類中,過載SetPathName,遮蔽其預設實現,更改為:
void CXXXDoc::SetPathName(LPCTSTR lpszPathName, BOOL bAddToMRU) { m_strPathName = lpszPathName; //直接將傳入名作為最後的文件名 m_bEmbedded = FALSE; //(不是嵌入物件) SetTitle(lpszPathName); //設定標題(可具體更改) }
當實際使用時,對每個文件模板,其OpenDocumentFile對要新增很多程式碼,很不方便, 這是,可以將共用部分建立成成員函式
例:
CDocument * CXXXApp::OpenWithTemplate(CMultiDocTemplate * pDocTemplate,LPCTSTR lpszFileName) { if(pDocTemplate) { CDocument* pOpenDocument = NULL; pDocTemplate-> MatchDocType(lpszFileName, pOpenDocument); //避免重複開啟 if (pOpenDocument != NULL) { POSITION pos = pOpenDocument-> GetFirstViewPosition(); if (pos != NULL) { CView* pView = pOpenDocument-> GetNextView(pos); // get first one ASSERT_VALID(pView); CFrameWnd* pFrame = pView-> GetParentFrame(); if (pFrame != NULL) pFrame-> ActivateFrame(); else TRACE0("Error: Can not find a frame for document to activate.n"); CFrameWnd* pAppFrame; if (pFrame != (pAppFrame = (CFrameWnd*)AfxGetApp()-> m_pMainWnd)) { ASSERT_KINDOF(CFrameWnd, pAppFrame); pAppFrame-> ActivateFrame(); } } else { TRACE0("Error: Can not find a view for document to activate.n"); } return pOpenDocument; } else return pDocTemplate-> OpenDocumentFile(lpszFileName); } else return NULL; }
【: history.back()">回上一頁】
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-1004168/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MFC中文件檢視框架和文件模板之間的關係框架
- Visual C++ 6.0的文件/視結構 (轉)C++
- 將預設檢視改為“文件結構圖”
- 文件管理 | 文件目錄結構和檔案情況的檢視與匯出
- XForms文件結構 (轉)ORM
- Django的檢視和模板Django
- 檢視sqlite中的表結構SQLite
- 在列印視窗,列印檢視View的子檢視結構圖View
- 自己總結的V$檢視(轉)
- Qt 5模型/檢視結構QT模型
- 樹結構的應用
- Linux 下樹形結構的檢視Linux
- prtconf aix --檢視AIX的結構資訊AI
- 兩種檢視oracle表結構的方法Oracle
- Oracle常用檢視錶結構命令Oracle
- 檢視DB2表結構DB2
- 使用treedump事件檢視索引結構事件索引
- 微信小程式-檢視模板微信小程式
- .net core EF Core 檢視的應用
- 應用程式結構
- Oracle 如何高效的檢視官方文件Oracle
- 如何檢視python文件Python
- gdb golang 檢視iface 內部結構Golang
- 語法檢視錶結構,索引mysql索引MySql
- openoffice如何顯示文件的文件結構或目錄結構
- 資料結構學習(C++)——單連結串列應用(一元多項式【1】) (轉)資料結構C++
- 資料結構學習(C++)——單連結串列應用(一元多項式【2】) (轉)資料結構C++
- 全文字檢索的應用(2)(轉)
- 全文字檢索的應用(1)(轉)
- ThinkPHP框架檢視詳細介紹View檢視–模板(九)PHP框架View
- HTML文件結構HTML
- Delphi6/7 中XML 文件的應用 (轉)XML
- 【資料結構】棧的應用--數制轉換(c++)資料結構C++
- HarmonyOS:應用程式包結構(1)Stage模型應用程式包結構模型
- 資料結構模板資料結構
- 模板 - 資料結構資料結構
- 【模板】資料結構資料結構
- 文件 檢視 框架視窗間的關係和訊息傳送規律 (轉)框架