我們知道,在一般的MDI應(yīng)用程序中,只有一個文檔模板,程序只能打開一種類型的文檔。因此,只要調(diào)用File/New或者File/Open創(chuàng)建或者打開文檔即可,至于文檔、視和框架窗口之間的關(guān)系,則由文檔模板在幕后控制,不須要對文檔模板進行操作。
但是,如果應(yīng)用程序需要處理多種類型的文檔,并且何時打開何種文檔均需手工控制的話,此時,就必須對文檔模板進行編程。
例如,我們需要處理FIRST和SECOND兩種文件類型。其中FIRST和SECOND的數(shù)據(jù)存放格式不同,就不能用相同的數(shù)據(jù)結(jié)構(gòu)來描述,因此,把它們的數(shù)據(jù)都存入一個文檔是不合適的,若FIRST和SECOND的視也是不同的(比如一個是圖像而另一個是聲音),因此,要解決這個問題只能分別建立兩套文檔模板,兩套框架窗口,兩套文檔和兩套視,分別用于存放和顯示FIRST和SECOND 的數(shù)據(jù)。并且程序可以根據(jù)文件名來分別處理FIRST和SECOND 類型的文件。其主要步驟如下:
(1)在應(yīng)用程序類(CWinApp)的派生類的InitInstance()函數(shù)中修改相應(yīng)部分,增加程序所處理的文檔模板,如下所示:
CMultiDocTemplate* pFirstDocTemplate;
pFirstDocTemplate = new CMultiDocTemplate(
IDR_FIRSTTYPE,
RUNTIME_CLASS(CFirstDoc), //指定第一種類型文件的文檔類
RUNTIME_CLASS(CFirstFrame), //指定第一種類型文件的子框架
RUNTIME_CLASS(CFirstView)); //指定第一種類型文件的視
AddDocTemplate(pFirstDocTemplate); //為第一種類型的文檔添加模板
CMultiDocTemplate* pSecondDocTemplate;
pSecondDocTemplate = new CMultiDocTemplate(
IDR_SECONDTYPE,
RUNTIME_CLASS(CSecondDDoc), //指定第二種類型文件的文檔類
RUNTIME_CLASS(CSecondFrame), //指定第二種類型文件的子框架
RUNTIME_CLASS(CSecondView)); //指定第二種類型文件的視
AddDocTemplate(pSecondDocTemplate); //為第二種類型的文檔添加模板
(2)在應(yīng)用程序中增加菜單響應(yīng):
void CWinApp::OnFileOpen()
{
POSITION P = GetFirstDocTemplatePosition();
CFileDialog Dlg(true);
if(Dlg.DoModal()= =IDOK)
{
CString FileName = Dlg.GetPathName();
CString FileExt = Dlg.GetFileExt();
if((FileExt=="First")||(FileExt=="first")||(FileExt=="FIRST"))
{
while(P!=NULL)
{
CDocTemplate* curTemplate=GetNextDocTemplate(P);
CString str;
curTemplate->GetDocString(str,CDocTemplate::docName);
if(str= =_T("First"))
{
curTemplate->OpenDocumentFile(FileName);
return;
}
}
}
else if((FileExt = = "Second") || (FileExt = = "second")||(FileExt= =SECOND"))
{
while(P!=NULL)
{
CDocTemplate* curTemplate=GetNextDocTemplate(P);
CString str;
curTemplate->GetDocString(str,CDocTemplate::docName);
if(str==_T("Second"))
{
curTemplate->OpenDocumentFile(FileName);
return;
}
}
}else
{
// may not be supported
AfxMessageBox("你所選的文件類型本程序不支持!");
return;
}
}
} 這里把文件名的后綴作為分支條件,如果是First類文件,則先獲得關(guān)于First類文件的文檔模板,然后調(diào)用CDocTemplate::OpenDocumentFile (lpszFileName)函數(shù)打開此文檔。此函數(shù)將依次生成新文檔,新框架,并在框架中創(chuàng)建視,最后向框架中所有的視發(fā)送初始化消息,使其顯示在屏幕上。如果是Second類文件,操作類似。
當(dāng)然,我們還可以在程序的任何位置實現(xiàn)此操作:通過全局函數(shù)AfxGetApp 獲得應(yīng)用程序?qū)ο笾羔?,從而獲得相應(yīng)的文檔模板指針。
但是,如果應(yīng)用程序需要處理多種類型的文檔,并且何時打開何種文檔均需手工控制的話,此時,就必須對文檔模板進行編程。
例如,我們需要處理FIRST和SECOND兩種文件類型。其中FIRST和SECOND的數(shù)據(jù)存放格式不同,就不能用相同的數(shù)據(jù)結(jié)構(gòu)來描述,因此,把它們的數(shù)據(jù)都存入一個文檔是不合適的,若FIRST和SECOND的視也是不同的(比如一個是圖像而另一個是聲音),因此,要解決這個問題只能分別建立兩套文檔模板,兩套框架窗口,兩套文檔和兩套視,分別用于存放和顯示FIRST和SECOND 的數(shù)據(jù)。并且程序可以根據(jù)文件名來分別處理FIRST和SECOND 類型的文件。其主要步驟如下:
(1)在應(yīng)用程序類(CWinApp)的派生類的InitInstance()函數(shù)中修改相應(yīng)部分,增加程序所處理的文檔模板,如下所示:
CMultiDocTemplate* pFirstDocTemplate;
pFirstDocTemplate = new CMultiDocTemplate(
IDR_FIRSTTYPE,
RUNTIME_CLASS(CFirstDoc), //指定第一種類型文件的文檔類
RUNTIME_CLASS(CFirstFrame), //指定第一種類型文件的子框架
RUNTIME_CLASS(CFirstView)); //指定第一種類型文件的視
AddDocTemplate(pFirstDocTemplate); //為第一種類型的文檔添加模板
CMultiDocTemplate* pSecondDocTemplate;
pSecondDocTemplate = new CMultiDocTemplate(
IDR_SECONDTYPE,
RUNTIME_CLASS(CSecondDDoc), //指定第二種類型文件的文檔類
RUNTIME_CLASS(CSecondFrame), //指定第二種類型文件的子框架
RUNTIME_CLASS(CSecondView)); //指定第二種類型文件的視
AddDocTemplate(pSecondDocTemplate); //為第二種類型的文檔添加模板
(2)在應(yīng)用程序中增加菜單響應(yīng):
void CWinApp::OnFileOpen()
{
POSITION P = GetFirstDocTemplatePosition();
CFileDialog Dlg(true);
if(Dlg.DoModal()= =IDOK)
{
CString FileName = Dlg.GetPathName();
CString FileExt = Dlg.GetFileExt();
if((FileExt=="First")||(FileExt=="first")||(FileExt=="FIRST"))
{
while(P!=NULL)
{
CDocTemplate* curTemplate=GetNextDocTemplate(P);
CString str;
curTemplate->GetDocString(str,CDocTemplate::docName);
if(str= =_T("First"))
{
curTemplate->OpenDocumentFile(FileName);
return;
}
}
}
else if((FileExt = = "Second") || (FileExt = = "second")||(FileExt= =SECOND"))
{
while(P!=NULL)
{
CDocTemplate* curTemplate=GetNextDocTemplate(P);
CString str;
curTemplate->GetDocString(str,CDocTemplate::docName);
if(str==_T("Second"))
{
curTemplate->OpenDocumentFile(FileName);
return;
}
}
}else
{
// may not be supported
AfxMessageBox("你所選的文件類型本程序不支持!");
return;
}
}
} 這里把文件名的后綴作為分支條件,如果是First類文件,則先獲得關(guān)于First類文件的文檔模板,然后調(diào)用CDocTemplate::OpenDocumentFile (lpszFileName)函數(shù)打開此文檔。此函數(shù)將依次生成新文檔,新框架,并在框架中創(chuàng)建視,最后向框架中所有的視發(fā)送初始化消息,使其顯示在屏幕上。如果是Second類文件,操作類似。
當(dāng)然,我們還可以在程序的任何位置實現(xiàn)此操作:通過全局函數(shù)AfxGetApp 獲得應(yīng)用程序?qū)ο笾羔?,從而獲得相應(yīng)的文檔模板指針。