MFC中CPropertySheet與CTabCtrl的使用

一、控件的介紹

MFC中封裝了許多有用的類,CTabCtrl和CPropertySheet是其中兩個比較常用的類型。CTabCtrl即Tab控件對應的類,Windows應用程序中大量使用了Tab控件。屬性頁對應的是CPropertySheet,你在桌面上右鍵鼠標彈出的顯示對話框就是一個CPropertySheet類型的對象。事實上這類彈出的、類似“屬性頁”的窗口大部分都是CPropertySheet。

其實,這兩個類之間也有着很密切的聯繫。使用Spy++觀察一個屬性頁窗口可以發現,它也包含了一個Tab控件


二、屬性頁的使用

屬性頁的使用比較簡單,過程也很清晰。先說一下,CPropertySheet和CDialog對話框類同樣都派生於CWnd類,所以他倆在使用上有很多相似的地方。我不知道是不是這哥倆太相似了,以至於Spy++把我自建的一個CPropertySheet窗口認作是CDialog。

既然屬性頁和對話框相似,我們只要有了一個屬性頁的類,就可以使用DoModal()方法來產生一個模態的窗口,或者用Create()產生一個非模態的窗口。注意如果顯示非模式的窗口,要考慮變量生存期的問題,這點和非模態對話框是一樣的。

屬性頁窗口裏面那麼多的選項卡是怎麼弄出來的?這就需要CPropertyPage。這是一個對話框類的子類,對應着一個選項卡。對一個屬性頁,我們使用AddPage()方法來添加選項卡

選項卡既然是對話框,我們就可以在資源窗口中建立對話框,然後利用類嚮導爲他建立類,注意要選擇派生自CPropertyPage。MSDN上面說,建立這類對話框資源模板時有幾點要注意

1.保留TitleBar屬性。對話框標題就是將來顯示在選項卡上的標籤

2.對話框風格設爲Child,邊框設爲Thin

3.將對話框設爲Disabled

好了,總結一下屬性頁的使用步驟就是

1.建立模板資源,構造你需要的每一個CPropertyPage。

2.使用CPropertySheet類,用AddPage()方法爲其添加至少一個選項卡。或者,你可以派生一個自己的CMyPropertySheet類,在內部添加上各個CPropertyPage作爲成員變量,並在構造函數中用AddPage

3.在需要使用屬性頁的地方聲明變量,使用DoModal()或者Create()方法顯示屬性頁


三、Tab控件的使用

Tab控件一般用在對話框中。在我看來Tab控件本身並不複雜,其實也就是一組簡單的按鈕而已,因爲它並不能直接對各個選項卡進行操縱。我們需要對用戶選擇選項卡的行爲進行手工地響應

比如你希望對每一個選項卡顯示不同的內容,你必須通過顯示/隱藏不需要的內容。當每一個選項卡上的內容較多時,可以把這些內容放在一個容器裏,比如一個對話框。這樣,一個選項卡對應一個對話框,關係比較清晰。這些對話框應設置爲沒有標題欄、Child風格、無邊框的、非模式的。以此爲例,對話框中使用Tab控件的步驟是

1.在對話框中添加Tab控件

2.爲各選項卡建立對話框模板資源

3.響應Tab控件的TCN_SELCHANGE消息,在OnSelChange()函數中,用ShowWindow()函數顯示欲顯示的選項卡,隱藏其他。非模式對話框的生存期問題這裏仍然存在,不可忽視

4.初始化Tab控件。可在對話框初始化時手工調用OnSelChange()函數的方法來實現.


下面使用使用CTabCtrl或CPropertySheet實現標籤頁:

CTabCtrl

1.先建立一個MFC應用程序,然後在資源管理器中新建一對話框,併爲它建立對應的類,然後從工具箱裏面把Tab Control控件放入該對話框中。

再在對話框類中,聲明一個CTabCtrl變量:

CTabCtrl m_tab;

變量m_tab用來與對話框中的Tab Control控件交互,爲此要在DoDataExchange函數中加入DDX_Control語句:

DDX_Control(pDX, IDC_TAB_NEW, m_tab);

IDC_TAB_NEW是Tab Control控件的ID。

2.建立兩個新對話框,用來當做Tab Control控件的兩個頁。別忘了把Style改爲Child,Border改爲None。然後就可以在上面加其他控件了。

接着分別爲這兩個對話框建立兩個類,比如CPage1和CPage2。

然後在對話框類頭文件中,加入這兩個對話框對象。同時增加一個變量int m_CurSelTab,用了表明是哪個Page即將被切換。

int m_CurSelTab; 
CPage1 m_page1; 
CPage2 m_page2; 
CDialog* pDialog[2];  //用來保存對話框對象指針

在對話框類的初始化函數中需要把CPage1、CPage2和Tab Control關聯起來,並保存頁面地址,設置初始頁面。

//爲Tab Control增加兩個頁面  
m_tab.InsertItem(0, _T("Farm"));  
m_tab.InsertItem(1, _T("Note"));  
  
//創建兩個對話框  
m_page1.Create(IDD_DIALOG1, &m_tab);  
m_page2.Create(IDD_DIALOG2, &m_tab);  
  
//設定在Tab內顯示的範圍  
CRect rc;  
m_tab.GetClientRect(rc);  
rc.top += 20;  
  
m_page1.MoveWindow(&rc);  
m_page2.MoveWindow(&rc);  
  
//把對話框對象指針保存起來  
pDialog[0] = &m_page1;  
pDialog[1] = &m_page2;  
  
//顯示初始頁面  
pDialog[0]->ShowWindow(SW_SHOW);  
pDialog[1]->ShowWindow(SW_HIDE);  
  
//保存當前選擇  
m_CurSelTab = 0;

這裏我們用了一個CDialog指針數組來進行保存Tab Control的每個頁,數組的大小是Tab Control頁面的個數,數組下標對應着每個頁面的索引(這樣方便快速存取)。接下來,爲Tab Control添加消息處理程序:

ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_NEW, &CTabDlg::OnTcnSelchangeTabNew)

void CTabDlg::OnTcnSelchangeTabNew(NMHDR *pNMHDR, LRESULT *pResult)  
  
{  
    //把當前的頁面隱藏起來   
    pDialog[m_CurSelTab]->ShowWindow(SW_HIDE);  
  
    //得到新的頁面索引   
    m_CurSelTab = m_tab.GetCurSel();  
  
    //把新的頁面顯示出來   
    pDialog[m_CurSelTab]->ShowWindow(SW_SHOW);  
    *pResult = 0;  
}

3.如果要在Tab Control控件外面獲取其內部對話框中控件的數據,就需要使用DDX/DDV機制,還要調用相應的UpdateData函數。

m_page1.UpdateData(); 

m_page2.UpdateData();


CPropertySheet

1.先建立MFC應用程序然後在資源管理器中新建一對話框,併爲它建立對應的類,在編輯該對話框,可以自由加一些所需的控件,但得留出一定的空間用於放至

標籤頁。在主對話框類里加入一個CPropertySheet類的一個成員變量m_sheet代表整個標籤頁。

2.接着分別爲創建兩個對話框,建立兩個與之對應的類時,注意選擇基類爲CPropertyPage。假設新生成兩個類爲CPage1,CPage2。

3.在剛纔加入m_sheet成員的位置,加入上述類型成員變量m_page1,m_page2。

CPropertySheet m_sheet;

CPage1        m_page1;

Cpage2         m_page2;

在主對話框類的OnInitDialog()函數中加入:

//加入標籤,標籤名由各個子對話框的標題欄決定   
m_sheet.AddPage(&m_page1);  
m_sheet.AddPage(&m_page2);  
  
//對修改標籤頁title   
m_page1.m_psp.dwFlags|=PSP_USETITLE;   
m_page1.m_psp.pszTitle= "標籤頁A";   
  
m_page2.m_psp.dwFlags|=PSP_USETITLE;   
m_page2.m_psp.pszTitle= "標籤頁B";   
  
//用Create來創建一個屬性頁   
m_sheet.Create(this, WS_CHILD | WS_VISIBLE, WS_EX_CONTROLPARENT);  
  
//調整m_sheet位置   
RECT rect;  
GetWindowRect(&rect);  
m_sheet.MoveWindow(&rect);



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章