VS2010&MFC对话框编程(3)——属性页对话框

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_NAMEm_name(CString)
1组合框(性别)IDC_COMBO_SEXm_sex(int)
1编辑框(年龄)IDC_EDIT_AGEm_age(CString)
2复选框(乒乓球)IDC_CHK_TBLTENNISm_tbltennis(BOOL)
2复选框(篮球)IDC_CHK_BSKBALLm_bskball(BOOL)
2复选框(游泳)IDC)CHK_SWIMm_swim(BOOL)
2复选框(网球)IDC_CHK_TENNISm_tennis(BOOL)
3单选按钮组(职务)--------------(可以用第一个按钮添加变量)m_job(int)
3列表框(工作地点)IDC_LIST_CITYm_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>
   
// 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);
}

.......................
    
    <Page2.h>
   
#pragma once


// CPage2 对话框

class CPage2 : public CPropertyPage
{
	...............................
public:
	BOOL m_tbltennis;
	BOOL m_bskball;
	BOOL m_swim;
	BOOL m_tennis;
	............................
};

    <Page2.cpp>
   
......................
//对成员变量初始化
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);
}
.....................................

    <Page3.h>
   
#pragma once


// CPage3 对话框

class CPage3 : public CPropertyPage
{
	...................
public:
	int m_job;
	CString m_city;
	...................
};

    <Page3.cpp>
   
// 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

    创建并显示属性页对话框
    在这里用菜单调用属性页,在原标准菜单后面添加新菜单“对话框”,在其下新建菜单命令“属性页对话框”,ID为IDM_PROP,利用“Event Handler Wizard”为其添加事件处理程序,这里选择基类为“CDialogView类(因为是在菜单中调用)”


创建并显示属性页对话框的页码如下
   
void CDialogView::OnProp()
{
	// TODO: 在此添加命令处理程序代码

	CPropertySheet propSheeet;
	//定义3个属性页的页面对象
	CPage1 page1;
	CPage2 page2;
	CPage3 page3;
	//将页面加入到属性页对话框的框架对象中
	propSheeet.AddPage(&page1);
	propSheeet.AddPage(&page2);
	propSheeet.AddPage(&page3);
	propSheeet.DoModal();
}

    <说明>

    (1)属性页对话框创建过程与普通对话框类似,不同在于还需将页对象加入到CPropertySheet对象中。
    (2)如果创建的是模态对话框,应调用CPropertySheet::DoModal(),如果创建非模态对话框,调用CPropertySheet::Create();
    (3)在CDialogView类的头文件中将新建3个页类的头文件包含进来,这是因为在CDialogView类的菜单命令的出来了函数OnProp中使用这三个类
              #include“Page1.h”
              #include“Page2.h”
              #include“Page3.h”

    运行结果:


    步骤6

    在各个页的重载OnInitDialog()函数,添加代码

    <Page1.cpp>
   
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
}
    
    <Page3.cpp>
   
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 

    将用户输入的数据显示在屏幕上
    为实现这一功能,至少在CDialogView类的头文件中定义一些相应的成员变量来保护用户的输入,代码如下
    
    <DialogView.h>
   

// DialogView.h : CDialogView 类的接口
//
.......................

class CDialogView : public CView
{
..........................
public:
	//注意:此处定义的成员变量与控件添加的成员变量同名,这样是为了方便记忆
	CString m_name;//对应于姓名编辑框的成员变量
	CString m_age;//对应于年龄编辑框的成员变量
	CString m_city;//对应于工作地点列表框的成员变量
	CString m_sex;//对应于性别组合框的成员变量
};
......................

    <注意>

    在CDialogView类中定义的成员变量和为控件的成员变量的同名,这样是为了方便记忆

    <DialogView.cpp>
   
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);
	}
}

    运行结果:


  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值