在應用程序的開發中,有些用戶可能需要解決這樣一個問題:對于某類型的一個文檔需要用不同的視圖顯示并且處理,來實現對文檔的多視圖操作。筆者也曾經開發過此類型的應用程序。但筆者在參考了一些關于這方面的書籍以后,感覺到關于一個文檔創建多個視圖的實現方法寫的比較少,有些參考書雖然提到了,但是其中的內容不夠具體,參照實現起來比較困難。這里,筆者介紹一種Visual
C++ 5.0環境下一個文檔創建多個視圖的易于實現的方法,供讀者參考(以三個視圖為例)。
下面是實現步驟:
創建新項目
運行Microsoft開發者工作室New選項,用MFC AppWizard(.exe)創建一個新的Project(項目),取名為Demo。
筆者在這里創建的是基于多文檔的(MDI)應用程序,所以在創建項目時,在MFCAppWizard
Step1窗口中要設置Multiple documents選項。這樣,項目Demo編譯連接以后生成Demo.exe。運行的結果是:每次打開一個文檔就會顯示一個視圖。如果要創建基于單文檔的(SDI)應用程序,可以設置Single
document選項?,F在項目Demo中已經包含了下面幾個類:
增加項目Demo中的類
打開項目Demo,選擇View菜單中的ClassWizard(類向導)的選項,用類向導對話框中的Addclass
下的New選項增加下面幾個新類到項目中,分別是CFirstView、CSecondView、CFirstFrame和CSecondFrame。
CFirstView、CSecondView的基礎類筆者選擇的是CView,CFirstFrame、CSecondFrame的基礎類是CMDIChildWnd。這樣項目Demo中就多了下面幾個類:
編輯Demo.h文件
需要建立三個文檔模板,分別對應三個視圖。因為文檔模板提供了MFC用來將文檔、視、框架結合在一起的框架結構。這里的文檔模板是用于MDI應用程序的CMultiDocTemplate(用于SDI應用程序的是CSingleDocTemplate),因此要在類CDemoApp聲明中增加三個公有型的成員變量:
class CDemoApp:public CWinApp
{
public:
CDemoApp();
CMultiDocTemplate *pDocTemplate;
CMultiDocTemplate *pFirstTemplate;
CMultiDocTemplate *pSecondTemplate;
∥Overrides
....
DECLARE_MESSAGE_MAP()
};
編輯Demo.cpp文件
首先,在Demo.cpp的頭部增加四條#include指令:
?。nclude “FirstFrame.h”
?。nclude “SecondFrame.h”
?。nclude “FirstView.h”
?。nclude “SecondView.h”
然后,需要在應用程序的模板列表中增加兩個文檔模板。需要將新增的兩個視圖與文檔CDemoDoc對應起來,同時新增的兩個視圖要分別使用新增的MDI子窗口CFirstFrame和CSecondFrame,在CDemoApp::
InitInstance中作如下修改:
pDocTemplate=newCMultiDocTemplate(
IDR_DEMOTYPE,
RUNTIME_CLASS(CDemoDoc),
RUNTIME_CLASS(CChildFrame),
∥用戶自定義MDI子窗口框架
RUNTIME_CLASS(CDemoView));
AddDocTemplate(pDocTemplate);
pFirstTemplate=newCMultiDocTemplate(
IDR_DEMOTYPE,
RUNTIME_CLASS(CDemoDoc),
RUNTIME_CLASS(CFirstFrame),
∥用戶自定義MDI子窗口框架
RUNTIME_CLASS(CFirstView));
AddDocTemplate(pFirstTemplate);
pSecondTemplate=newCMultiDocTemplate(
IDR_DEMOTYPE,
RUNTIME_CLASS(CDemoDoc),
RUNTIME_CLASS(CSecondFrame),
∥用戶自定義MDI子窗口框架
RUNTIME_CLASS(CSecondView));
AddDocTemplate(pSecondTemplate);
編輯類CFirstView和類CSecondView
首先,加入下列成員變量:
pubilc:
CDemoDoc *GetDocument();
到FirsView.h和SecondView.h。
接著,對FirstView.cpp用如下修改:
void CFirstView::OnDraw(CDC *oDC)
{
CDemoDoc *pDoc=GetDocument();
∥TODO:add draw code here
}
....
?。fdef _DEBUG
.....
CDemoDoc *CFirstView::GetDocunent()
{
ASSERT(m_pDocument→IsKindOf
(RUNTIME_CLASS(CDemoDoc)));
return(CDenidDoc *)m_pDocument;
}
?。ndif ∥_DEBUG
然后,加入下列代碼到SecondView.cpp中:
void CSecondView::OnDraw(CDC *pDC)
{
CDemoDoc *pDoc=GetDocument();
∥TODO:add draw code here
}
...
?。fdef _DEBUG
....
CDemoDoc *CSecondView::GetDocument()
{
ASSERT(m_pDocument→IsKindOf(RUNTIME_CLASS(CDemoDoc)));
return(CDemodDoc *)m_pDocument;
}
?。ndif ∥_DEBUG
現在,在CFirstView.cpp,CSecondView.cpp的開頭分別加入下面一條#include指令:
?。nclude “DemoDoc.h”
編輯DemoDoc.h文件
由于一個文檔創建三個視圖,即文檔要使用三個MDI子窗口,因此首先要在類CDemoDoc的聲明中增加三個公有型的成員變量:
class CDemoDoc:public CDocument
{
....
∥Attributes
public:
CChildFrame *pChildFrame;
CFirstFrame *pFirstFrame;
CSecondFrame *pSecondFrame;
∥Operations
....
DECLARE_MESSAGE_MAP()
};
同時,在DemoDoc.h的頭部增加三條#include 指令:
?。nclude “ChildFrm.h”
?。nclude “FirstFrame.h”
?。nclude “SecondFrame.h”
編輯CDemoView::OnInitialUpdate
應用程序打開一個現有的文檔,為了打開另外新增的兩個視,就需要調用文檔模板的CreateFrame()成員。另外兩個新增的文檔模板將文檔類型和兩個新增的視類聯系起來,因此,在OnInitialUpdate中增加下列代碼:
vokd CDemoView::OnInitialUpdate()
{
CView::OnInitialUpadate()
...
CDemoDoc *pDoc=GetDocument();
ASSERT_VALID(pDoc);
CMainFrame *pAppFrame=(CMainFrame *)
AfxGetApp()→m_pMainWnd;
ASSERT_KINDOF(CMainFrame,pAppFrame);
pDoc→pChildFrame=(CChildFrame *)GetParentFrame();
CMultiDocTemplat *pFirstTemplate=((CDemoApp *)AfxGetApp())→pFirstTemplate;
ASSERT_VALID(pFirstTemplate);
pDoc→pFirstFrame=(CFirstFrame *)pFirstTemplate→CreateNewFrame(pDoc,pAppFrame);
pFirstTemplate→InitialUpdateFrame(pDoc→pFirstFrame,pDoc);
CMultiDocTemplate *pSecondTemplate=((CDemoApp *)AfxGetApp())→pSecondTemplate;
ASSERT_VALID(pSecondTemplate);
pDoc→pSecondFrame=(CSecondFrame *)pSecondFrame→CreateNewFrame(pDoc,pAppFrame);
pSecondTemplate→InitialUpdateFrame(pDoc→pSecondFrame,pDoc);
}
調用InitialUpdateFrame()函數,是對視圖的窗口框架進行初始化。而后,在文件DemoView.cpp的開頭,增加如下七條#include指令:
?。nclude “Windows.h”
?。nclude “Windowsx.h”
?。nclude “MainFrm.h”
?。nclude “FirstFrame.h”
?。nclude “SecondFrame.h”
?。nclude “FirstView.h”
?。nclude “SecondView.h”
修改串資源
由于有三個文檔模板,為了防止工作框認為有多個文檔類型,需要對IDR_DEMOTYPE的Caption(標題)進行修改。將“\n\Demo\nDemo\n\n\n\Demo.Document\nDemoDocument”
改成
“\n\Demo\n\n\n\n\Demo.Document\nDemoDocument”。
經過上述幾個步驟以后,就可以實現一個文檔創建多個視圖。最后的事情就是進行編譯連接。對于上述的實現方法有興趣的讀者不防一試?!?nbsp;