小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

(轉(zhuǎn))VC隨筆——切分窗口和多視圖

 浮 生 2009-04-14

動態(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,代碼如下:

 CSplitterWnd m_wndSplitter; //用于產(chǎn)生靜態(tài)切分

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)切分窗口:

 m_wndSplitter.CreateStatic(this, 1, 2);

4、使用CreateView產(chǎn)生每個視圖窗口

當(dāng)用戶建立一靜態(tài)切分窗口時,應(yīng)當(dāng)同時建立窗口內(nèi)的所以區(qū)域??梢栽贠nCreateClient函數(shù)中添加如下代碼來為第一行第一列的窗格產(chǎn)生視圖:

 m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CMy2DCADView),

                               CSize(450, 250), pContext);

其中,第3個參數(shù),視圖類的執(zhí)行期類CRuntimeClass指針,可以用宏RUNTIME_CLASS來獲得。

注意:(1)必須為每一個靜態(tài)切分窗口創(chuàng)建視圖窗口,不能漏掉一個

      (2)由于使用到了視圖類,因此,必須包含相應(yīng)的類的頭文件。在MainFrm.cpp文件的開始部分包括以下兩個頭文件:

#include "2DCADDoc.h"
#include "2DCADView.h"

      (3)產(chǎn)生靜態(tài)切分后,就不能再調(diào)用默認(rèn)情況下的基類的OnCreateClient函數(shù)。因此,應(yīng)該將下面的代碼刪除或者注釋掉:

// return CFrameWnd::OnCreateClient(lpcs, pContext);

最后,完整的CMainFrame::OnCreateClient函數(shù)代碼如下:

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
 // TODO: Add your specialized code here and/or call the base class
 //使用CreateStatic函數(shù)產(chǎn)生靜態(tài)切分
 m_wndSplitter.CreateStatic(this, //父窗口指針
        1,  //行數(shù)
        2);  //列數(shù)

 //使用CreateView為第1個窗格產(chǎn)生視圖
 m_wndSplitter.CreateView(0, 0, //窗格的行、列序數(shù)
       RUNTIME_CLASS(CMy2DCADView), //視圖類
       CSize(450, 250), //初始化大小
       pContext);   //父窗口的創(chuàng)建參數(shù)

 //使用CreateView為第2個窗格產(chǎn)生視圖
 m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CMy2DCADView),
        CSize(450, 250), pContext);

 return 1; //不再調(diào)用基類的OnCreateClient函數(shù)
// return CFrameWnd::OnCreateClient(lpcs, pContext);
}

這時,用戶在一個視圖中所作的修改還不能立刻反映到其他視圖窗口中,還應(yīng)添加相應(yīng)的通知視圖重畫的代碼。

5、通知視圖重畫

文檔類有一個名為UpdateAllViews的函數(shù),可以在文檔數(shù)據(jù)發(fā)生改變時通知所有的視圖窗口重畫。

在視圖類的OnLButtonDown函數(shù)中每個調(diào)用SetModifiedFlag函數(shù)的后面立即調(diào)用UpdateAllViews的函數(shù),代碼如下:

...

   pDoc->SetModifiedFlag(); //設(shè)置文檔“臟”標(biāo)志
   pDoc->UpdateAllViews(this); //重畫所有視圖

...

 

向當(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)建第二個窗口視圖的代碼如下:

 //使用CreateView為第2個窗格產(chǎn)生視圖
 m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CTextView),//使用文本視圖類
        CSize(250, 250), pContext);

由于使用到了新的視圖類,因此,應(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)建第二個窗口視圖的代碼如下:

 //使用CreateView為第2個窗格產(chǎn)生視圖
 m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CColorForm),//使用表單視圖類
        CSize(250, 250), pContext);

由于使用到了新的視圖類,因此,應(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ù)注冊該模板對象。

 //這是應(yīng)用程序框架生成的代碼
 CMultiDocTemplate* pDocTemplate;
 pDocTemplate = new CMultiDocTemplate(
  IDR_MUTTYPE,
  RUNTIME_CLASS(CMutDoc),
  RUNTIME_CLASS(CChildFrame), // custom MDI child frame
  RUNTIME_CLASS(CMutView));
 AddDocTemplate(pDocTemplate);

 //創(chuàng)建新的文檔模板對象
 pDocTemplate = new CMultiDocTemplate(
  IDR_TEXTTYPE,    //新創(chuàng)建的字符串資源、圖標(biāo)資源和菜單資源
  RUNTIME_CLASS(CMutDoc),  //仍舊使用原來的文檔類
  RUNTIME_CLASS(CTextFrame), //新添加的子框架窗口類
  RUNTIME_CLASS(CTextView)); //新添加的文本視圖類
 //將新的文檔模板對象加入到應(yīng)用程序中。
 AddDocTemplate(pDocTemplate);

由于使用到了新的視圖類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ù)注冊該模板對象。

 //創(chuàng)建三叉靜態(tài)切分的文檔模板對象
 pDocTemplate = new CMultiDocTemplate(
  IDR_THREETYPE,    //用于三叉靜態(tài)切分窗口的字符串資源、圖標(biāo)資源和菜單資源
  RUNTIME_CLASS(CMutDoc),  //仍舊使用原來的文檔類
  RUNTIME_CLASS(CThreeFrame), //新添加的三叉切分子框架窗口類
  RUNTIME_CLASS(CColorForm)); //新添加的表單視圖派生類
 //將新的文檔模板對象加入到應(yīng)用程序中。
 AddDocTemplate(pDocTemplate);

由于使用到了新的視圖類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)
{
 // TODO: Add your specialized code here and/or call the base class

 //使用CreateStatic函數(shù)產(chǎn)生第一次靜態(tài)切分
 m_wndSplitter1.CreateStatic(this, //父窗口指針
        1,  //行數(shù)
        2);  //列數(shù),一行兩列

 //使用CreateView為第1個窗格產(chǎn)生CColorForm視圖
 m_wndSplitter1.CreateView(0, 0, //窗格的行、列序數(shù)
       RUNTIME_CLASS(CColorForm), //表單視圖類
       CSize(250, 250),   //初始化大小
       pContext);     //父窗口的創(chuàng)建參數(shù)

 //再次使用CreateStatic函數(shù)對第一次切分產(chǎn)生的第二個窗口靜態(tài)切分
 m_wndSplitter2.CreateStatic(
    &m_wndSplitter1,  //父窗口是第一次的切分窗口
    2, 1,     //將這個窗口切分成兩行一列
    WS_CHILD | WS_VISIBLE, //窗口風(fēng)格
    m_wndSplitter1.IdFromRowCol(0, 1)
   //指出新切分的窗口是上一次分隔的第一行第二個窗口
   );

 //使用CreateView為第二次切分的第1個窗格產(chǎn)生視圖
 m_wndSplitter2.CreateView(0, 0, RUNTIME_CLASS(CTextView),//使用文本視圖類
        CSize(150, 120), pContext);

 //使用CreateView為第二次切分的第2個窗格產(chǎn)生視圖
 m_wndSplitter2.CreateView(1, 0, RUNTIME_CLASS(CMutView),//使用CMutView視圖類
        CSize(250, 250), pContext);
 
 return 1; //不再調(diào)用基類的OnCreateClient函數(shù)
// return CMDIChildWnd::OnCreateClient(lpcs, 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"

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多