1、简介
属性页对话框实际上是一个包含多个子对话框的对话框,这些子对话框通常被称为页(Page),每次只有一个页是可见的,在对话框的顶端有一行的选项卡,可通过点击不同的选项卡切换到不同的页。这样就可以容纳大量的控件来描述某一对象的诸多属性。
属性页对话框包括一个CPropertySheet和几个CPropertyPage。
2、创建属性页对话框例子
步骤1
新建一个MFC单文档应用程序,工程名为Dialog
步骤2
分别为各个页创建对话框模板
资源面板插入3个对话框
修改Caption属性分别改为“个人信息”、“兴趣爱好”、“工作情况”
修改ID分别为IDD_PAGE1、IDD_PAGE2、IDD_PAGE3。每页默认的“OK”和“Cancel”按钮去掉
由于每个对话框对应于属性页对话框的一个页面,样式有特殊要求:Style ---Child;Boder---Thin;Tilte Bar---True;Disable---True;
<注意>
每页的模板最好有相同的尺寸,若不统一,则框架将根据最大的页来确定属性页对话框的大小
步骤3
为每个页创建新类
用Class Wizard分别为每个页创建CPropertyPage类的派生类,三个属性页相似,相对应的修改“MFC Class Wizard”对话框中:Class name---填写类名(CPage1)、在Base class(基类) ---选择CPropertyPage;
步骤4
为每页的对话框添加控件及其相对应的成员变量
第一页3个静态正文控件,Caption分别为:“姓名”、“性别”、“年龄”
两个编辑框、一个组合框,ID分别为:IDC_EDIT_NAME、IDC_COMBO_SEX、IDC_EDIT_AGE
<注意>
(1)由于组合框的作用是让用户选择性别,个数较少的情况下,可以先赋初值,在组合框的属性中的Data页面完成(男;女;)
(2)将组合框的Type属性设为Drop List,用户不能再输入数据,此时的组合框只能捆绑int类型的成员变量
第二页四个复选框控件
Caption分别为:乒乓球、篮球、游泳、网球
ID分别为:IDC_CHK_TBLTENNIS、IDC_CHK_BSKBALL、IDC)CHK_SWIM、IDC_CHK_TENNIS
第三页有两个组框、三个单选按钮和一个列表框
组框---Caption分别为:职务、工作地点
单选按钮---Caption分别为:程序员、软件工程师、系统分析师
---ID分别为IDC_RAD_PRO、IDC_RAD_SOFT、IDC_RAD_ANALY
列表框---ID为IDC_LIST_CITY
<注意>
(1)单选按钮设为一组,将第一个单选按钮的Group属性选中,一组单选按钮只能捆绑一个int性成员变量,表示该组中选中的单选按钮的序号
(2)列表框中的数据要通过在OnInitDialog()中用户手动添加
给每个页的控件添加对应的成员变量,可以通过“AddMember Variable Wizard”对话框添加,选择“Member Variable”页面,然后选中“Control Variable”复选框,Control ID-----选择响应的控件ID;Variable name-----输入变量名;Category-----选择“Value”选项;Variable type -----选择相应的变量类型
页面 | 控件类型 | ID 号 | 成员变量 |
1 | 编辑框(姓名) | IDC_EDIT_NAME | m_name(CString) |
1 | 组合框(性别) | IDC_COMBO_SEX | m_sex(int) |
1 | 编辑框(年龄) | IDC_EDIT_AGE | m_age(CString) |
2 | 复选框(乒乓球) | IDC_CHK_TBLTENNIS | m_tbltennis(BOOL) |
2 | 复选框(篮球) | IDC_CHK_BSKBALL | m_bskball(BOOL) |
2 | 复选框(游泳) | IDC)CHK_SWIM | m_swim(BOOL) |
2 | 复选框(网球) | IDC_CHK_TENNIS | m_tennis(BOOL) |
3 | 单选按钮组(职务) | --------------(可以用第一个按钮添加变量) | m_job(int) |
3 | 列表框(工作地点) | IDC_LIST_CITY | m_city(CString) |
<注意>
控件的成员变量的命名和控件的ID号相关,这样方便记忆,不易混淆。
<说明>
对话框类添加控件的控件成员变量后,相应的头文件(.h)和源文件(.cpp)中会有相应的代码写入
<Page1.h>
#pragma once
// CPage1 对话框
class CPage1 : public CPropertyPage
{
.....................
public:
CString m_name;
int m_sex;
CString m_age;
........................
};
// Page1.cpp : 实现文件
//
.......................
//对变量初始化
CPage1::CPage1()
: CPropertyPage(CPage1::IDD)
, m_name(_T(""))
, m_sex(0)
, m_age(_T(""))
{
}
................
//消息映射
void CPage1::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT_NAME, m_name);
DDX_CBIndex(pDX, IDC_COMBO_SEX, m_sex);
DDV_MinMaxInt(pDX, m_sex, 0, 1);
DDX_Text(pDX, IDC_EDIT_AGE, m_age);
}
.......................
#pragma once
// CPage2 对话框
class CPage2 : public CPropertyPage
{
...............................
public:
BOOL m_tbltennis;
BOOL m_bskball;
BOOL m_swim;
BOOL m_tennis;
............................
};
......................
//对成员变量初始化
CPage2::CPage2()
: CPropertyPage(CPage2::IDD)
, m_tbltennis(FALSE)
, m_bskball(FALSE)
, m_swim(FALSE)
, m_tennis(FALSE)
{
}
..........................
//消息映射
void CPage2::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
DDX_Check(pDX, IDC_CHK_TBLTENNIS, m_tbltennis);
DDX_Check(pDX, IDC_CHK_BSKBALL, m_bskball);
DDX_Check(pDX, IDC_CHK_SWIM, m_swim);
DDX_Check(pDX, IDC_CHKTENNIS, m_tennis);
}
.....................................
#pragma once
// CPage3 对话框
class CPage3 : public CPropertyPage
{
...................
public:
int m_job;
CString m_city;
...................
};
// Page3.cpp : 实现文件
//
.............................
//成员变量初始化
CPage3::CPage3()
: CPropertyPage(CPage3::IDD)
, m_job(0)
, m_city(_T(""))
{
}
................................
//消息映射
void CPage3::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
DDX_Radio(pDX, IDC_RAD_PRO, m_job);
DDX_LBString(pDX, IDC_LIST_CITY,m_city);
}
..........................
步骤5
void CDialogView::OnProp()
{
// TODO: 在此添加命令处理程序代码
CPropertySheet propSheeet;
//定义3个属性页的页面对象
CPage1 page1;
CPage2 page2;
CPage3 page3;
//将页面加入到属性页对话框的框架对象中
propSheeet.AddPage(&page1);
propSheeet.AddPage(&page2);
propSheeet.AddPage(&page3);
propSheeet.DoModal();
}
<说明>
步骤6
BOOL CPage1::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: 在此添加额外的初始化
((CComboBox*)GetDlgItem(IDC_COMBO_SEX))->SetCurSel(1);
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
BOOL CPage3::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: 在此添加额外的初始化
//将城市信息添加到列表框
((CListBox*)GetDlgItem(IDC_LIST_CITY))->AddString(_T("北京"));
((CListBox*)GetDlgItem(IDC_LIST_CITY))->AddString("上海");
((CListBox*)GetDlgItem(IDC_LIST_CITY))->AddString("深圳");
((CListBox*)GetDlgItem(IDC_LIST_CITY))->AddString("天津");
//高亮显示第一条信息
((CListBox*)GetDlgItem(IDC_LIST_CITY))->SetCurSel(0);
((CButton*)GetDlgItem(IDC_RAD_PRO))->SetCheck(1);
//默认第一条消息为高亮度显示
((CListBox*)GetDlgItem(IDC_LIST_CITY))->SetCurSel(0);
((CButton*)GetDlgItem(IDC_RAD_PRO))->SetCheck(1);
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
步骤7
// DialogView.h : CDialogView 类的接口
//
.......................
class CDialogView : public CView
{
..........................
public:
//注意:此处定义的成员变量与控件添加的成员变量同名,这样是为了方便记忆
CString m_name;//对应于姓名编辑框的成员变量
CString m_age;//对应于年龄编辑框的成员变量
CString m_city;//对应于工作地点列表框的成员变量
CString m_sex;//对应于性别组合框的成员变量
};
......................
<注意>
void CDialogView::OnProp()
{
// TODO: 在此添加命令处理程序代码
CPropertySheet propSheeet;
//定义3个属性页的页面对象
CPage1 page1;
CPage2 page2;
CPage3 page3;
//将页面加入到属性页对话框的框架对象中
propSheeet.AddPage(&page1);
propSheeet.AddPage(&page2);
propSheeet.AddPage(&page3);
/*propSheeet.DoModal();*/
if(propSheeet.DoModal() == IDOK)//判断用户是否点击“确定”按钮退出
{
//获取并显示用户第一页的输入信息
m_age = page1.m_age;
m_name = page1.m_name;
if(page1.m_sex == 0)
m_sex = "男";
else
m_sex = "女";
if(m_name.IsEmpty())//判断用户是否输入姓名
{
MessageBox("您没有输入姓名,不能显示!");
return ;
}
if(m_age.IsEmpty())//判断用户是否输入年龄
{
MessageBox("您没有输入年龄,不能显示!");
return ;
}
CClientDC dc(this);
CString strInput;
strInput = "姓名:";
strInput +=m_name;
strInput +=", 性别:";
strInput +=m_sex;
strInput +=", 年龄";
strInput +=m_age;
dc.TextOut(0,0,strInput);
//获取并显示第二页输入的信息
strInput = "爱好:";
if(page2.m_tbltennis)//乒乓球复选框是否被选中
strInput +=" 乒乓球 ";
if(page2.m_bskball)
strInput +=" 篮球 ";
if(page2.m_swim)
strInput +=" 游泳 ";
if(page2.m_tennis)
strInput +="网球 ";
TEXTMETRIC tm;
dc.GetTextMetrics(&tm);//获取当前字体的高度
dc.TextOut(0,tm.tmHeight,strInput);
//获取并显示用户第三页输入的信息
strInput = "职务:";
if(page3.m_job == 0)
strInput +="程序员";
if(page3.m_job == 1)
strInput += "软件工程师";
if(page3.m_job == 2)
strInput += "系统分析师";
m_city = page3.m_city;
strInput +=", 工作地点:";
strInput +=m_city;
dc.TextOut(0,2*tm.tmHeight,strInput);
}
}