1、分類
標簽式和向導式
2、相關類
CPropertyPage -屬性頁,其實就是一個對話框頁面,父類是CDialog類
CPropertySheet -屬性表單,父類是CWnd類
一個完整的屬性頁對話框由一個屬性表單+多個屬性頁組成
屬性頁資源與普通對話框資源的區別:
屬性頁:
對話框:
3、標簽式屬性頁
3.1插入屬性頁對話框資源,修改語言和字體,雙擊資源,生成相應的類,注意父類選擇CPropertyPage類。
創建一個單文檔視圖的MFC工程:Prop
插入3個屬性頁:
注意:①這里插入的3個屬性頁資源的語言均為“English(U.S.)”,須右擊資源修改屬性為中文語言
②3個屬性頁Page1、Page2、Page3的字體默認均為“MS Sans Serif”,點擊“字體[O]...”按鍵修改字體為中文字體
利用MFC類向導生成相應的屬性頁類:
3.2類視圖下右擊工程,選擇添加新的類,父類是CPropertySheet類。
3.3在屬性表單中添加屬性頁對象,在屬性表單類的構造函數中調用 CPropertySheet::AddPage
首先在在屬性表單對象CPropSheet的頭文件PropSheet.h中分別把先前創建的三個屬性頁的頭文件包含進來:
#include "Prop1.h"
#include "Prop2.h"
#include "Prop3.h"
然后在屬性表單對象CPropSheet的頭文件PropSheet.h中為三個屬性頁分別定義成員變量:
public:
CProp1 m_prop1;
CProp2 m_prop2;
CProp3 m_prop3;
屬性表單類有兩個構造函數,在構造屬性表單對象時,可任選其一構造函數,調用AddPage函數添加屬性頁對象:
CPropSheet::CPropSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage) :CPropertySheet(nIDCaption, pParentWnd, iSelectPage) { AddPage(&m_prop1); AddPage(&m_prop2); AddPage(&m_prop3); } CPropSheet::CPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage) :CPropertySheet(pszCaption, pParentWnd, iSelectPage) { AddPage(&m_prop1); AddPage(&m_prop2); AddPage(&m_prop3); }
3.4創建顯示屬性表單 CPropertySheet::Domodal()
在Prop程序的主菜單上添加一個菜單項,用戶單擊這個菜單項后,程序顯示屬性表單;
在視圖類中添加該菜單項的消息響應函數
在CPropView類的源文件開始部分包含CPropSheet類的頭文件:
#include "stdafx.h"
#include "Prop.h"
#include "PropDoc.h"
#include "PropView.h"
#include "PropSheet.h"
在程序新添加的菜單項的響應函數中,調用DoModal函數顯示一個模式化的屬性表單:
void CPropView::OnPropertysheet() { // TODO: Add your command handler code here CPropSheet propSheet("屬性表單"); propSheet.DoModal(); }
構造的CPropSheet類型的屬性表對象propSheet調用的是以標題為參數的屬性表單構造函數;
3.5當控件的值發生改變時,將應用按鈕設置為可用 CPropertyPage::SetModified(TRUE);
3.6消息處理(通過在頁面類中添加虛函數的方式實現)
CPropertyPage::OnApply
CPropertyPage::OnOK
CPropertyPage::OnCancel
4、向導式屬性頁
4.1插入屬性頁對話框資源,修改語言和字體,雙擊資源,生成相應的類,注意父類選擇CPropertyPage類。
4.2類視圖下右擊工程,選擇添加新的類,父類是CPropertySheet類。
4.3在表單類中添加屬性頁對象,在構造函數中調用 CPropertySheet::AddPage
---------------------------------之前的步驟與標簽式屬性頁中創建屬性表單的實現步驟一致
4.4創建和顯示前,設置為向導模式 CPropertySheet::SetWizardMode
void CPropView::OnPropertysheet() { // TODO: Add your command handler code here CPropSheet propSheet("屬性表單"); propSheet.SetWizardMode(); propSheet.DoModal(); }
4.5創建和顯示 CPropertySheet::DoModal()
4.6設置每個頁面的向導按鈕
1--在 CPropertyPage::OnSetActive() 函數中設置
2--在屬性頁中獲取表單對象的指針 GetParent()
3--設置向導按鈕 CPropertySheet::SetWizardButtons()
void SetWizardButtons( DWORD dwFlags );
dwFlags:PSWIZB_BACK / PSWIZB_NEXT / PSWIZB_FINISH / PSWIZB_DISABLEDFINISH
首先在第一個屬性頁的類CProp1中右擊添加虛函數OnSetActive,第一個屬性頁應該只有【下一步】和【取消】
BOOL CProp1::OnSetActive() { // TODO: Add your specialized code here and/or call the base class ((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_NEXT); return CPropertyPage::OnSetActive(); }
為第二個屬性頁CProp2添加OnSetActive虛函數,第二個屬性頁應該有【上一步】【下一步】和【取消】
BOOL CProp2::OnSetActive() { // TODO: Add your specialized code here and/or call the base class ((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK|PSWIZB_NEXT); return CPropertyPage::OnSetActive(); }
再為第三個屬性頁CProp3添加OnSetActive函數,第三個屬性頁應該有【上一步】和【完成】
BOOL CProp3::OnSetActive() { // TODO: Add your specialized code here and/or call the base class ((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK|PSWIZB_FINISH); return CPropertyPage::OnSetActive(); }
在資源窗口的第一個屬性頁資源上,為單選按鈕組關聯一個成員變量
注意:單選按鈕組的第一個單選按鈕的屬性中的“組”要勾選,以標識這幾個單選按鈕為一組,只能選擇其一;
利用MFC類向導添加成員變量:
默認會在CProp1類的構造函數中將m_occupation變量初始化為-1
在選中單選按鈕組的第一個單選按鈕時,關聯的成員變量m_occupation的值變為0;選中第二個單選按鈕變為1;選中第三個單選按鈕變為2;
為CProp1類添加OnWizardNext虛函數,完成對屬性頁上【下一步】按鈕的命令響應:
LRESULT CProp1::OnWizardNext() { // TODO: Add your specialized code here and/or call the base class //須調用UpdateData函數以調用DoDataExchange來完成控件與成員變量的數據交換 UpdateData(TRUE); if(m_occupation==-1){ MessageBox("請選擇你的職業"); return -1; } return CPropertyPage::OnWizardNext(); }
要在屬性頁顯示前向列表框中添加顯示內容,為CProp1類添加WM_INITDIALOG消息的響應函數OnInitDialog;列表框控件有個相應的MFC類:CListBox,利用其成員函數AddString可向列表框添加字符:
BOOL CProp1::OnInitDialog() { CPropertyPage::OnInitDialog(); // TODO: Add extra initialization here ((CListBox*)GetDlgItem(IDC_LIST1))->AddString("北京"); ((CListBox*)GetDlgItem(IDC_LIST1))->AddString("上海"); ((CListBox*)GetDlgItem(IDC_LIST1))->AddString("廣州"); ((CListBox*)GetDlgItem(IDC_LIST1))->AddString("深圳"); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }
利用MFC類向導給列表框控件關聯一個成員變量m_workAddr:
LRESULT CProp1::OnWizardNext() { // TODO: Add your specialized code here and/or call the base class //調用UpdateData函數以調用DoDataExchange來完成控件與成員變量的數據交換 UpdateData(TRUE); if(m_occupation==-1){ MessageBox("請選擇你的職業"); return -1; } if(m_workAddr==""){ MessageBox("請選擇你的工作地點"); return -1; } return CPropertyPage::OnWizardNext(); }
在資源窗口的第二個屬性頁資源上,為四個復選框分別關聯成員變量
程序自動將復選框控件關聯的各個成員變量初始化,當復選框控件被選中時,所關聯的成員變量的值為TRUE,否則為FALSE;
為CProp2類添加OnWizardNext虛函數,以在點擊【下一步】時檢查用戶是否點選復選框
LRESULT CProp2::OnWizardNext() { // TODO: Add your specialized code here and/or call the base class UpdateData(TRUE); if(m_football || m_basketball || m_volleyball || m_swim){ return CPropertyPage::OnWizardNext(); }else{ MessageBox("請選擇你的興趣愛好"); return -1; } }
為第三個屬性頁的CProp3類添加WM_INITDIALOG消息的響應函數OnInitDialog;組合框對應的MFC類為CComboBox,利用該類的成員函數AddString向組合框控件的列表框中添加選項;
BOOL CProp3::OnInitDialog() { CPropertyPage::OnInitDialog(); // TODO: Add extra initialization here ((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("10000元以下"); ((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("10000-20000元"); ((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("20000-30000元"); ((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("30000元以上"); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }
要是組合框的下拉選項的順序和添加的順序一樣,須勾選掉資源窗口中組合框資源的屬性中樣式里的“分類”:
要使得組合框中在顯示時有一個默認的選中項,須使用SetCurSel函數實現:
int SetCurSel(int nSelect);
參數為選項的位置索引;如果為-1,則將移除組合框的當前選項並清空編輯框中的內容;
BOOL CProp3::OnInitDialog() { CPropertyPage::OnInitDialog(); // TODO: Add extra initialization here ((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("10000元以下"); ((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("10000-20000元"); ((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("20000-30000元"); ((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("30000元以上"); ((CComboBox*)GetDlgItem(IDC_COMBO1))->SetCurSel(0); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }
為第三個屬性頁CProp3類添加成員變量:CString m_strSalary,用來接收用戶的選擇;給CProp3類添加虛函數:OnWizardFinish,用來處理【完成】按鈕的單擊消息;
為了獲取用戶在第三個屬性頁CProp3中的組合框的選擇項,須先利用GetCurSel函數獲得組合框中當前選項的位置,再利用GetLBText函數獲得組合框的相應位置的對應字符串;
BOOL CProp3::OnWizardFinish() { // TODO: Add your specialized code here and/or call the base class int index; index=((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCurSel(); ((CComboBox*)GetDlgItem(IDC_COMBO1))->GetLBText(index,m_strSalary); return CPropertyPage::OnWizardFinish(); }
為了接收用戶在向導類屬性列表的各個屬性頁中的選擇,在程序的視圖類中須定義相應的成員變量來保存;
然后在視圖類的構造函數中初始化這些成員變量:
CPropView::CPropView() { // TODO: add construction code here m_iOccupation=-1; m_strWorkAddr=""; memset(m_bLike,0,sizeof(m_bLike)); //對數組m_bLike進行快速初始化 m_strSalary=""; }
判斷只有當用戶點擊的是【完成】按鈕,程序才接收各個屬性頁中的選擇項:
void CPropView::OnPropertysheet() { // TODO: Add your command handler code here CPropSheet propSheet("屬性表單"); propSheet.SetWizardMode(); if(ID_WIZFINISH==propSheet.DoModal()){ m_iOccupation=propSheet.m_prop1.m_occupation; m_strWorkAddr=propSheet.m_prop1.m_workAddr; m_bLike[0]=propSheet.m_prop2.m_football; m_bLike[1]=propSheet.m_prop2.m_basketball; m_bLike[2]=propSheet.m_prop2.m_volleyball; m_bLike[3]=propSheet.m_prop2.m_swim; m_strSalary=propSheet.m_prop3.m_strSalary; Invalidate(); } }
4.7消息處理函數
虛函數:
OnSetActive()--當屬性頁被選中時,使其成為當前的活動頁面
OnCancel()--單擊屬性頁的【取消】按鈕時程序調用該虛函數
OnWizardNext()--單擊屬性頁上【下一步】按鈕時程序調用該虛函數;如果返回0,則自動進入當前向導的下一個屬性頁;如果返回-1,屬性頁不發生變化;
OnWizardBack()--單擊屬性頁【上一步】按鈕時程序調用該虛函數
OnWizardFinish()--單擊屬性頁【完成】按鈕時程序調用該虛函數