目錄
屬性頁編寫總體思路
CPropertySheet 編程
Tab Control 控件
(本章節中例子都是用 VS2005 編譯調試的)
屬性頁編寫總體思路
大體思想:
設置對話框屬性頁屬性:
屬性名 值
System Menu False
Style Child
Title Bar False
Border None
代碼樣例(這里我一幾個按鈕控件來演示):
添加兩個對話框資源並為對話框資源定義相關屬性,資源 ID 為IDD_PAGE1,IDD_PAGE2,資源視圖如下所示:
為主對話框添加相關成員變量(屬性頁關聯對象,CDialog 數組指針,當前顯示標簽頁的索引)代碼如下:

//記錄當前顯示頁面的索引 int m_CurSelTab; //屬性頁對話框對象 CPage1 m_p1; CPage2 m_p2; //對話框數組 CDialog* pDialog[2];
在主對話框的 OnInitDialog 函數中初始化屬性頁相關操作,添加的具體代碼如下:

//創建兩個對話框,並將 CTabCtrl 對象作為其父窗口 m_p1.Create(IDD_PAGE1, this); m_p2.Create(IDD_PAGE2, this); //把對話框對象與 CDialog 數組聯系起來 pDialog[0] = &m_p1; pDialog[1] = &m_p2; //獲得 Tab Control 客戶區矩形大小 CRect rc; GetClientRect(rc); //調整矩形大小讓屬性頁顯示在適當的位置上 rc.top += 2; rc.bottom -= 2; rc.left += 2; rc.right -= 200; //移動對話框窗口到矩形區域中 m_p1.MoveWindow(&rc); m_p2.MoveWindow(&rc); //顯示初始頁面,保存當前選擇 pDialog[0]->ShowWindow(SW_SHOW); pDialog[1]->ShowWindow(SW_HIDE); m_CurSelTab = 0;
然后為對話框添加兩個按鈕並通過這個兩個按鈕的事件響應函數來實現屬性頁的切換,具體代碼如下:

/* 按鈕一實現把屬性頁切換到第一個頁面 *******************/ void CtestDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知處理程序代碼 //把當前的頁面隱藏起來 pDialog[m_CurSelTab]->ShowWindow(SW_HIDE); //設置新的頁面索引 m_CurSelTab = 0; //把新的頁面顯示出來 pDialog[m_CurSelTab]->ShowWindow(SW_SHOW); } /* 按鈕二實現把屬性頁切換到第二個頁面 *******************/ void CtestDlg::OnBnClickedButton2() { // TODO: 在此添加控件通知處理程序代碼 //把當前的頁面隱藏起來 pDialog[m_CurSelTab]->ShowWindow(SW_HIDE); //設置新的頁面索引 m_CurSelTab = 1; //把新的頁面顯示出來 pDialog[m_CurSelTab]->ShowWindow(SW_SHOW); }
運行結果:
CPropertySheet 編程
對話框屬性頁資源
普通對話框資源和屬性頁資源對話框的區別:
選項 普通對話框 屬性頁對話框
Style Popup Child
Border Dialog Thin
System menu 選中 未選中
可以把普通對話框按照上面修改便可以稱為屬性頁對話框
創建對話框屬性頁資源
編寫CPropertySheet流程圖:
代碼樣例:
屬性頁模式
創建兩個屬性頁資源 ID 為 IDD_PAGE1 與 IDD_PAGE2,並關聯兩個 CPropertyPage 派生類,類分別為 CPage1,CPage2.資源視圖如下:
CPage1 與 CPage2 源碼:

// 因為大致是一樣的所以這里以 CPage1 文件為例子,不一樣的地方我也列了出來 /* CPage1 CPage2 對話框頭文件 ***************************/ class CPage1 : public CPropertyPage //class CPage2 : public CPropertyPage { DECLARE_DYNAMIC(CPage1) //DECLARE_DYNAMIC(CPage2) public: CPage1(); //CPage2(); virtual ~CPage1(); //virtual ~CPage2(); // 對話框數據 enum { IDD = IDD_PAGE1 }; //enum { IDD = IDD_PAGE2 }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() }; /* CPage1 CPage2 對話框實現文件 *************************/ IMPLEMENT_DYNAMIC(CPage1, CPropertyPage) //IMPLEMENT_DYNAMIC(CPage2, CPropertyPage) CPage1::CPage1() : CPropertyPage(CPage1::IDD) //CPage2::CPage2() // : CPropertyPage(CPage2::IDD) { } CPage1::~CPage1() //CPage2::~CPage2() { } void CPage1::DoDataExchange(CDataExchange* pDX) //void CPage2::DoDataExchange(CDataExchange* pDX) { CPropertyPage::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CPage1, CPropertyPage) //BEGIN_MESSAGE_MAP(CPage2, CPropertyPage) END_MESSAGE_MAP()
在工程中添加一個派生於 CPropertySheet 類,這里我不它命名為 CMyProSh,然后在 CMyProSh 中添加 CPage1,CPage2 對象作為其成員變量,並在構造函數中用 AddPage 函數把 CPage1,CPage2 對象添加到屬性表單中去.CMyProSh 程序源碼如下:

//MyProSh.h #pragma once #include "Page1.h" #include "Page2.h" class CMyProSh : public CPropertySheet { CPage1 m_p1; CPage2 m_p2; ... } //MyProSh.cpp CMyProSh::CMyProSh(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage) :CPropertySheet(nIDCaption, pParentWnd, iSelectPage) { this->AddPage(&m_p1); this->AddPage(&m_p2); } CMyProSh::CMyProSh(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage) :CPropertySheet(pszCaption, pParentWnd, iSelectPage) { this->AddPage(&m_p1); this->AddPage(&m_p2); }
在主對話框中添加一個按鈕然后為按鈕添加事件響應函數,在函數中添加如下代碼:
//創建表單類對象 CMyProSh pro(L"表單樣例"); //顯示模態表單對話框 pro.DoModal();
運行結果:
向導模式:
相關函數:
- CPropertySheet::SetWizardButtons
- CPropertySheet::SetWizardMode
- CPropertyPage::OnWizardBack
- CPropertyPage::OnWizardFinish
- CPropertyPage::OnWizardNext
代碼樣例:
在創建模態對話框前的步驟與屬性頁模式一致.但在調用 DoModal 函數創建模態對話框前需要先調用 SetWizardMode 成員函數.代碼如下:

//創建表單類對象 CMyProSh pro(L"表單樣例"); //設置向導模式 pro.SetWizardMode(); //顯示模態表單對話框 pro.DoModal();
運行結果:
Tab Control 控件
說明:
Tab Control 的運行效果有點像 Property Sheet,但兩者還是有一些區別.我的理解就是Property Sheet主要用在對話框中,對數據進行進行分類管理.而 Tab Control 使用范圍更廣一些,既可以用在對話框,也可以用在視圖中,除了可以管理配置數據外,還可以對軟件的組織進行規划,比如可以通過它來切換不同的視圖等等,當然這不是沒有代價的,Tab Control 的編程就比 Property Sheet 的復雜很多.但是不是每個 Tab Control 的標簽頁對應一個頁面
對於客戶區其實只有一個,工作原理其實就是有許多的子對話框在客戶區上但是只有一個顯示而其他的都沒有顯示通過按標簽頁后相應事件讓現在顯示的子對話框隱藏而對應於標簽頁索引的某個子對話框顯示
相關函數:
CTabCtrl 類成員函數

[插入項][獲得標簽頁總數目][刪除對應標簽頁][刪除所有標簽頁][獲得標簽頁矩形空間][獲得當前標簽頁索引][設置某標簽頁為顯示標簽頁]
函數原型:
LONG InsertItem( int nItem, LPCTSTR lpszItem );
參數說明:
- nItem: 為插入位置
- lpszItem: 為標簽頁標題內容
作用: 插入一個新的標簽頁在tab control控件里面的nItem位置處,若nItem位置大於控件中標簽頁的總數則表明在最后的位置添加一個新的標簽頁
函數原型:
int GetItemCount( ) const
返回值: 返回控件中標簽頁的總數
函數原型:
BOOL DeleteItem( int nItem);
參數說明: nItem 要刪除的標簽頁的位置
作用: 刪除一個在nItem位置處以存在的標簽頁,若nItem位置大於控件中標簽頁的總數,它將不執行任何操作
函數原型:
BOOL DeleteAllItems( );
作用: 刪除控件中所有的標簽頁
函數原型:
BOOL GetItemRect( int nItem, LPRECT lpRect ) const;
參數說明:
- nItem: 要獲取矩形空間的標簽位置
- lpRect: 用於接收標簽的矩形空間
作用: 用 lpRect 來接收位置為 nItem 的標簽頁面上索引頁面的小矩形,而不是控件的客戶區
函數原型:
int GetCurSel( ) const;
返回值: 返回標簽頁的索引
函數原型:
int SetCurSel( int nItem );
參數說明: nItem 要設置為當前標簽頁的索引位置
作用: 用在nItem位置的標簽頁來作為當前顯示的標簽頁
CWnd 類成員函數

函數原型:
void GetClientRect(LPRECT lpRect ) const;
參數說明: lpRect 用於記錄客戶區矩形空間
說明: 獲得窗體的客服區的矩形記入在 lpRect 中
函數原型:
void MoveWindow(int x,int y,int nWidth,int nHeight,BOOL bRepaint = TRUE ); void MoveWindow(LPCRECT lpRect,BOOL bRepaint = TRUE );
參數說明:
- x: 移動到的區間的左上角橫坐標
- y: 移動到的區間的左上角縱坐標
- nWidth: 移動到的區間的寬度
- nHeight: 移動到的區間的高度
- bRepaint: 是否發生窗口重繪
- lpRect: 移動到的矩形區間
說明: 改變窗體類的位置和大小
BOOL ShowWindow( int nCmdShow );
參數取值:
- SW_HIDE
- SW_MINIMIZE
- SW_RESTORE
- SW_SHOW
- SW_SHOWMAXIMIZED
- SW_SHOWMINIMIZED
- SW_SHOWMINNOACTIVE
- SW_SHOWNA
- SW_SHOWNOACTIVATE
- SW_SHOWNORMAL
說明: 按nCmdShow方式顯示窗體
編寫流程圖:
代碼樣例:
在對話框上建立一個 Tab Control 控件,然后為控件添加關聯的控制變量,並為變量命名為 m_tab.資源對話如下圖所示:
添加兩個對話框資源並為對話框資源定義相關屬性,資源 ID 為IDD_PAGE1,IDD_PAGE2,資源視圖如下所示:
為主對話框添加相關成員變量(屬性頁關聯對象,CDialog 數組指針,當前顯示標簽頁的索引)代碼如下:

//Tab Control 控件關聯變量 CTabCtrl m_tab; //記錄當前顯示頁面的索引 int m_CurSelTab; //屬性頁對話框對象 CPage1 m_p1; CPage2 m_p2; //對話框數組 CDialog* pDialog[2];
在主對話框的 OnInitDialog 函數中初始化 Tab Control 控件,即在 OnInitDialog 函數中添加一下代碼:

//創建兩個對話框,並將 CTabCtrl 對象作為其父窗口 m_p1.Create(IDD_PAGE1, &m_tab); m_p2.Create(IDD_PAGE2, &m_tab); //把對話框對象與 CDialog 數組聯系起來 pDialog[0] = &m_p1; pDialog[1] = &m_p2; //為 Tab Control 增加兩個頁面 m_tab.InsertItem(0, _T("One")); m_tab.InsertItem(1, _T("Two")); //獲得 Tab Control 客戶區矩形大小 CRect rc; m_tab.GetClientRect(&rc); //調整矩形大小讓屬性頁顯示在適當的位置上 rc.top += 23; rc.bottom -= 2; rc.left += 2; rc.right -= 3; //移動對話框窗口到矩形區域中 m_p1.MoveWindow(&rc); m_p2.MoveWindow(&rc); //顯示初始頁面,保存當前選擇 pDialog[0]->ShowWindow(SW_SHOW); pDialog[1]->ShowWindow(SW_HIDE); m_CurSelTab = 0;
為 Tab Control 控件添加響應標簽頁選擇改變事件( 即 TCN_SELCHANGE 事件),然后在事件響應函數中添加切換屬性頁操作,相關代碼如下:

//把當前的頁面隱藏起來 pDialog[m_CurSelTab]->ShowWindow(SW_HIDE); //得到新的頁面索引 m_CurSelTab = m_tab.GetCurSel(); //把新的頁面顯示出來 pDialog[m_CurSelTab]->ShowWindow(SW_SHOW);
運行結果: