動態(tài)切分窗口:
動態(tài)切分窗口不能包含多于4個的窗格,要想得到4個以上的窗格,可以使用靜態(tài)切分窗口。動態(tài)切分窗口中的幾個窗格通常使用的是同一個視圖類。
創(chuàng)建動態(tài)切分窗口的方式共有3種:
1、在創(chuàng)建應(yīng)用程序時,利用應(yīng)用程序向?qū)ppWizard的選項(xiàng)設(shè)置切分窗口
2、在創(chuàng)建了應(yīng)用程序之后,通過添加組件對窗口進(jìn)行切分
3、通過手動添加代碼編程的方式
使用AppWizard創(chuàng)建動態(tài)切分:
在MFC AppWizard Step 4 of 6對話框中,單擊Advanced按鈕,彈出Advanced Options對話框,選擇Window Styles選項(xiàng)卡,選中該頁的Use split window檢查框。
使用Splitter Bar組件:
選擇Project|Add To Project|Components and Controls...菜單,彈出Components and Controls Gallery對話框。雙擊Visual C++ Components目錄,選擇Splitter Bar項(xiàng),插入Splitter Bar組件。
運(yùn)行程序,打開【查看】菜單或者是【窗口】菜單,找不到前面使用AppWizard添加動態(tài)切分時的【分隔】菜單項(xiàng)。說明Splitter Bar組件的方式并沒有添加相應(yīng)的菜單項(xiàng),程序員可以自己添加上去。
注意:菜單的Caption(標(biāo)題)可以隨便設(shè)定,但注意菜單項(xiàng)的ID必須是ID_WINDOW_SPLIT。ID_WINDOW_SPLIT是系統(tǒng)預(yù)先指定的,程序員一般不需要對此命令I(lǐng)D添加命令消息處理函數(shù),就可以實(shí)現(xiàn)分隔,因?yàn)镸FC應(yīng)用程序框架中已經(jīng)對該命令I(lǐng)D的消息進(jìn)行了處理。
手動添加代碼:
1、在框架窗口類(對單文檔為主框架窗口,對多文檔為子框架窗口)中聲明一個CSplitterWnd類的成員變量m_wndSplitter
2、使用ClassWizard為框架窗口類添加OnCreateClient函數(shù)
注意:這里使用ClassWizard是重寫父類的虛函數(shù),而不是添加消息處理
3、在OnCreateClient函數(shù)中調(diào)用CSplitterWnd類的成員函數(shù)Create產(chǎn)生動態(tài)切分
4、為應(yīng)用程序添加一個ID為ID_WINDOW_SPLIT的菜單項(xiàng)
CSplitterWnd切分窗口類:
CSplitterWnd的成員函數(shù)中,有3個使用非常頻繁
1、Create函數(shù)
創(chuàng)建一個動態(tài)的切分窗口
2、CreateStatic函數(shù)
創(chuàng)建一個靜態(tài)的切分窗口
3、CreateView函數(shù)
為靜態(tài)切分窗口創(chuàng)建視圖窗口。在框架顯示一個靜態(tài)切分窗口之前,該窗口的所有視圖窗格都必須已被創(chuàng)建好。當(dāng)動態(tài)切分窗口時,此函數(shù)被框架窗口自動調(diào)用。
靜態(tài)切分窗口:
靜態(tài)切分窗口是指在窗口創(chuàng)建時,切分窗口的窗格就已經(jīng)創(chuàng)建好了,且窗格的數(shù)量和順序不會改變。最多可以支持16行×16列的窗口(即256個窗格),但是必須在應(yīng)用程序中創(chuàng)建窗格,而且不同的窗口往往使用不同的視圖類。
創(chuàng)建靜態(tài)切分的步驟:
1、在框架窗口類中聲明一個CSplitterWnd類的成員變量m_wndSplitter
2、使用ClassWizard為框架窗口類添加OnCreateClient函數(shù)
3、在OnCreateClient函數(shù)中調(diào)用CSplitterWnd::CreateStatic產(chǎn)生靜態(tài)切分
4、在OnCreateClient函數(shù)中調(diào)用CSplitterWnd::CreateView產(chǎn)生每個切分的視圖窗口
為2DCAD應(yīng)用程序添加靜態(tài)切分功能:
1、聲明切分窗口類對象m_wndSplitter
為主框架窗口類CMainFrame添加保護(hù)成員變量m_wndSplitter,代碼如下:
2、在框架窗口類中添加OnCreateClient函數(shù)
打開ClassWizard,選中MessageMaps選項(xiàng)卡,在Class name中選擇CMainFrame類,在ObjectIDs列表中選擇CMainFrame,在Message列表框中雙擊OnCreateClient項(xiàng),為框架窗口添加OnCreateClient函數(shù)。
3、使用CreateStatic產(chǎn)生靜態(tài)切分
在OnCreateClient函數(shù)中添加如下代碼,就可以產(chǎn)生1×2的靜態(tài)切分窗口:
4、使用CreateView產(chǎn)生每個視圖窗口
當(dāng)用戶建立一靜態(tài)切分窗口時,應(yīng)當(dāng)同時建立窗口內(nèi)的所以區(qū)域??梢栽贠nCreateClient函數(shù)中添加如下代碼來為第一行第一列的窗格產(chǎn)生視圖:
其中,第3個參數(shù),視圖類的執(zhí)行期類CRuntimeClass指針,可以用宏RUNTIME_CLASS來獲得。
注意:(1)必須為每一個靜態(tài)切分窗口創(chuàng)建視圖窗口,不能漏掉一個
#include "2DCADDoc.h"
#include "2DCADView.h"
//
最后,完整的CMainFrame::OnCreateClient函數(shù)代碼如下:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
//
}
這時,用戶在一個視圖中所作的修改還不能立刻反映到其他視圖窗口中,還應(yīng)添加相應(yīng)的通知視圖重畫的代碼。
5、通知視圖重畫
文檔類有一個名為UpdateAllViews的函數(shù),可以在文檔數(shù)據(jù)發(fā)生改變時通知所有的視圖窗口重畫。
在視圖類的OnLButtonDown函數(shù)中每個調(diào)用SetModifiedFlag函數(shù)的后面立即調(diào)用UpdateAllViews的函數(shù),代碼如下:
...
...
向當(dāng)前工程中插入新類的兩種方式:
1、使用New Class對話框添加新類
(1)MFC ClassWizard中的New Class對話框
使用ClassWizard對話框中的Add Class...按鈕下的New...菜單項(xiàng)可以打開MFC ClassWizard對話框下的New Class對話框。這個對話框用來向當(dāng)前工程中添加派生自MFC類庫的新類。
(2)通用的New Class對話框
單擊菜單命令I(lǐng)nsert|New Class...可以打開一個通用的New Class對話框。實(shí)際上通用的New Class對話框相當(dāng)于包含了3個對話框,用于產(chǎn)生幾乎所有不同的類。
2、使用插入包含類定義的文件到當(dāng)前工程中
(1)將所需類的.h、.cpp文件復(fù)制到目標(biāo)工程目錄下
(2)打開目標(biāo)工程,單擊Project|Add To Project|Files...菜單項(xiàng)插入所需類的.h、cpp文件到目標(biāo)工程中
(3)在所需類的.cpp文件中,去掉包含原來的工程的頭文件語句(比如2DCAD.h),添加包含目標(biāo)工程的頭文件語句(比如Mut.h)
添加新的視圖類:
為2DCAD工程添加一個新的視圖類CTextView,單擊Insert|New Class...菜單項(xiàng),在New Class對話框中確保Class type中選擇的是MFC Class,在Name編輯框中輸入CTextView,在Base class下拉列表中指定基類為CEditView。
添加了新的視圖類之后,就可以在框架窗口的OnCreateClient函數(shù)中調(diào)用CreateView函數(shù)時使用這個新視圖類了。接下來使用CTextView作為靜態(tài)切分窗口中第二個窗格的視圖類,在OnCreateClient函數(shù)中修改創(chuàng)建第二個窗口視圖的代碼如下:
由于使用到了新的視圖類,因此,應(yīng)該在MainFrm.cpp文件的開始部分添加包含CTextView類頭文件的代碼:
#include "TextView.h"
注意:CEditView封裝了編輯框的功能,因此,如果要編寫文字處理軟件,可以使用CEditView作為視圖基類。CEditView最多支持64K的文本,如果需要支持更豐富的文本,可以使用CRichEditView作為視圖基類,但要包含頭文件afxrich.h。
表單視圖類CFormView:
CFormView就是可以在其中包含許多控件的視圖基類。這個類也像CDialog對話框類一樣,封裝了數(shù)據(jù)交換功能。甚至可以將CFormView理解為作為視圖的對話框。
1、創(chuàng)建對話框模板資源
(1)添加對話框模板,ID為IDD_FORMVIEW
(2)修改屬性
在Style選項(xiàng)卡中,設(shè)置Style選項(xiàng)為Child,Border選項(xiàng)為None,并去掉對Title Bar復(fù)選框的勾選。
注意:由于視圖類是一個子窗口,因此,必須設(shè)置Child選擇,否則程序不能正常運(yùn)行。
(3)添加控件
刪掉默認(rèn)的OK和Cancel按鈕,依次添加一個靜態(tài)文本、一個分組框和4個單選按鈕,同時為第一個單選按鈕添加上Group屬性。
注意:對一組單選按鈕來說,只需要對該組的第一個單選按鈕設(shè)置Group屬性就可以了。如果不設(shè)置Group屬性,就無法添加對應(yīng)的成員變量。
2、產(chǎn)生CFormView的派生類
(1)使用ClassWizard為IDD_FORMVIEW對話框模板資源添加一個名為CColorForm的視圖類,注意選擇基類為CFormView
(2)在Member Variables選項(xiàng)卡中為IDC_RADIO1添加一個名為m_nColor的整型成員變量
注意:對一組單選按鈕只能對帶有Group屬性的按鈕增加一個成員變量,并且這個成員變量必須是int型。0表示選擇第一個,依次類推,-1表示未選擇。
在CColorForm構(gòu)造函數(shù)中令成員變量m_nColor的初始值為0,表示選擇第一項(xiàng)。
3、修改切分窗口的視圖類
打開OnCreateClient函數(shù),修改創(chuàng)建第二個窗口視圖的代碼如下:
由于使用到了新的視圖類,因此,應(yīng)該在MainFrm.cpp文件的開始部分添加包含CColorForm類頭文件的代碼:
#include "ColorForm.h"
可以像處理無模式對話框那樣,在表單視圖類中添加相應(yīng)的消息處理函數(shù)。
一個多文檔多視圖的綜合示例:
下面綜合前面的知識,創(chuàng)建一個包含多文檔、多視圖、動態(tài)切分、三叉靜態(tài)切分以及可以支持多種文檔類型的綜合示例。
支持多種文檔類型:
在MFC應(yīng)用程序中,要增加附加的文檔類型,大致可分為以下幾步:
1、使用ClassWizard添加新的文檔類、子框架窗口類以及視圖類(如果需要的話)
2、利用資源編輯器為新的文檔類型添加字符串資源
3、利用資源編輯器添加附加的圖標(biāo)和菜單資源
4、創(chuàng)建新的文檔模板對象并加入到應(yīng)用程序中
5、完成文檔的序列化以及視圖的顯示交互工作
下面為Mut添加支持多文檔類型的功能(此時Mut本身是一個空的具有動態(tài)切分窗口的多文檔程序):
1、添加新的文檔類、子框架窗口類和視圖類
一般來說,一個新的文檔類型所需要的文檔類、外邊框窗口類和視圖類有可能都不同于已經(jīng)存在的類的,但也可能和現(xiàn)存的類相同(比如使用相同的子框架窗口)。因此,根據(jù)不同的需要會添加不同的類。這里,首先只添加一個新的視圖類和子框架窗口類,而文檔類則使用原來的類。
注意:多種文檔類型的各個文檔類一般是不同的
(1)添加新的視圖類的方法可以參加《向當(dāng)先工程中插入新類的兩種方式》中的第二種方式,插入2DCAD程序中所用到的可以輸入簡單的文本的CTextView類。
(2)添加新的子框架窗口類CTextFrame,基類選擇為CMDIChildWnd。具體方法參加向當(dāng)先工程中插入新類的兩種方式》中的第一種方式。
2、利用資源編輯器為新的文檔類型添加字符串資源
參照Mut應(yīng)用程序已經(jīng)存在的文檔模板字符串資源IDR_MUTTYPE,在字符串編輯器中增加一個新的字符串資源,指定ID為IDR_TEXTTYPE,內(nèi)容為:
\nText\n文本視圖窗口\nText Files(*.txt)\n.txt\nTextDocument\nText Document
可見文檔模板字符串包含7個由“\n”結(jié)尾并分隔的子串,最后一個字符串后面不需要“\n”。這些子串描述了文檔的類型,它們的含義按照順序分別如下:
(1)窗口標(biāo)題(2)文檔名(3)新建文檔類型名(4)過濾器名(5)文件擴(kuò)展名(6)文檔類型ID(7)注冊文檔類型名
3、利用資源編輯器添加附加的圖標(biāo)和菜單資源
(1)添加一個ID為IDR_TEXTTYPE的圖標(biāo),可以利用畫圖工具編輯之
(2)添加一個ID為IDR_TEXTTYPE的菜單,將IDR_MUTTYPE菜單資源下的【文件】、【編輯】、【查看】、【幫助】菜單復(fù)制到IDR_TEXTTYPE中。注意:可以使用右鍵菜單中的Insert Copy...,然后再修改。
注意:這些資源的ID必須同第二步中創(chuàng)建文檔模板字符串中所用的ID相同。
4、創(chuàng)建新的文檔模板對象并加入到應(yīng)用程序中
在應(yīng)用程序類CMutApp的InitInstance函數(shù)中,參照應(yīng)用程序框架生成的代碼,創(chuàng)建另一個CMultiDocTemplate對象,并用CWinApp::AddDocTemplate成員函數(shù)注冊該模板對象。
由于使用到了新的視圖類CTextView和新的子框架窗口類CTextFrame,因此應(yīng)該在Mut.cpp文件的開始部分包含它們的頭文件:
#include "TextView.h"
#include "TextFrame.h"
注意:此時Mut程序就包含有兩個文檔模板對象,可以支持兩種不同的文檔了,但是,它們使用了相同的文檔類,而實(shí)際應(yīng)用中應(yīng)該使用不同的文檔類。
5、完成文檔的序列化以及視圖的顯示交互工作
最后,根據(jù)用戶的需要,可以為文檔類添加上數(shù)據(jù)保存以及序列化功能,為視圖類添加相應(yīng)的顯示數(shù)據(jù)和交換功能。
多文檔的三叉靜態(tài)切分:
這三個窗口的排列方式類似“|—”形狀,所使用的視圖類分別類似前面2DCAD工程中創(chuàng)建的CColorForm類以及Mut工程中創(chuàng)建的CTextView類和CMutView類。
1、添加新的文檔模板對象
(1)添加新的視圖類和子框架窗口類
在Mut工程中創(chuàng)建一個和2DCAD工程中相同的CFormView類的派生類CColorForm。
注意:可以使用文件復(fù)制再插入的方法,還需要將所需的對話框資源模板以及控件的ID值定義都復(fù)制過來。
再添加一個派生自CMDIChildWnd類的CThreeFrame類,作為文檔的外邊框窗口。
(2)編輯資源
添加ID都為IDR_THREETYPE的三個資源,字符串資源,圖標(biāo)資源和菜單資源。其中,字符串資源如下:
\nThree\n三叉切分窗口\nThree Files(*.thr)\n.txt\nThreeDocument\nThree Document
(3)創(chuàng)建新的文檔模板對象
在應(yīng)用程序類CMutApp的InitInstance函數(shù)中,參照應(yīng)用程序框架生成的代碼,創(chuàng)建另一個CMultiDocTemplate對象,并用CWinApp::AddDocTemplate成員函數(shù)注冊該模板對象。
由于使用到了新的視圖類CColorForm和新的子框架窗口類CThreeFrame,因此應(yīng)該在Mut.cpp文件的開始部分包含它們的頭文件:
#include "ColorForm.h"
#include "ThreeFrame.h"
2、添加三叉靜態(tài)切分
(1)在子框架窗口類CThreeFrame中添加兩個CSplitterWnd類的保護(hù)成員變量m_wndSplitter1和m_wndSplitter2,分別用于產(chǎn)生第一次靜態(tài)切分和第二次靜態(tài)切分。
(2)使用ClassWizard為CThreeFrame添加OnCreateClient成員函數(shù)。
(3)改寫OnCreateClient成員函數(shù)代碼如下:
BOOL CThreeFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
//
}
可見產(chǎn)生第一次切分的方法是,先使用CreateStatic函數(shù)產(chǎn)生第一次切分,然后再使用CreateStatic函數(shù)對第一次切分所產(chǎn)生的窗口再次切分。
注意:第二次調(diào)用CreateStatic函數(shù)切分時,函數(shù)的參數(shù)有些變化:一是父窗口是第一次的切分窗口,二是ID必須是上次切分窗格的ID。
(4)在ThreeFrame.cpp文件的開始部分包含下列頭文件:
#include "MutDoc.h"
#include "MutView.h"
#include "TextView.h"
#include "ColorForm.h"




