对话框
一、“你能抓到我吗?”小游戏:
①创建一个新的对话框工程Test,用对话框的工具栏创建两个按钮,用ClassWizard创建一个针对这两个按钮的类CSuo。因为要将两者之一在开始的时候隐藏起来,所以要将其中之一的属性的Visible勾选去掉。
②再通过ClassWizard对这两个按钮增加两个控件变量到类CTestDlg中,并且在该类中包含上头文件#include “Suo.h”。
③在类CSuo中,添加一个CSuo类的指针变量p_btn。
④在CTestDlg类中的OnInitDialog()函数中,添加如下语句:
m_btn1.p_btn=&m_btn2;
		m_btn2.p_btn=&m_btn1;
//让按钮1的指针指向按钮2,按钮2的指针指向按钮1。OnInitDialog()函数是在对话框建立之前的瞬间调用的,故这两句要写到这里。
⑤在CSuo类中添加一个鼠标滑动消息接收函数:
void CSuo::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	ShowWindow(SW_HIDE);
	p_btn->ShowWindow(SW_SHOW);
	CButton::OnMouseMove(nFlags, point);
}
二、属性表单和向导的创建
属性表单的创建:
新建一个单文档工程Prop:
1、	在资源中,插入三个属性页资源,并修改属性页的ID和标题。
2、	在每个属性页中添加一些控件。
3、	对每一个属性页增加一个相对应的类,其基类是CPropertyPage,然后再增加一个属性表单的类CPropSheet,其基类是CPropertySheet。
4、	在CPropSheet类中,添加三个属性页的变量:
	CProp1 m_prop1;
	CProp2 m_prop2;
	CProp3 m_prop3;
5、	在CPropSheet类的构造函数中,添加如下语句:
AddPage(&m_prop1);
AddPage(&m_prop2);
AddPage(&m_prop3);//即是将属性页添加到属性表单中
6、	在菜单资源中,添加一个子菜单,并对其通过ClassWizard进行命令响应:
void CMainFrame::OnPropertysheet() 
{
	// TODO: Add your command handler code here
	CPropSheet PropSheet("索广宇的属性表单");
//在构建对象的过程中,就执行了构造函数中的AddPage函数,将属性页添加到属性表单中。
	PropSheet.DoModal();//调用此函数用来生成一个模态表单。
}
向导的创建:
向导的创建和属性表单的创建基本上是一样的,就是在第6步中的DoModal()之前,要添加上SetWizardMode()函数,就形成了向导。但要是实现第一个属性页没有上一步,最后一个属性页没有下一步,有完成按钮,就要调用SetWizardButtons()函数,具体实现细节如下:
1、	分别在创建的和属性页相对应的三个类中,通过ClassWizard重载一个OnSetActive()函数,在该函数中调用父窗口的成员函数SetWizardButtons()来设置属性页上的按钮的类型。
2、	实现代码如下:
OnSetActive()函数是当这个属性页被用户选中时,调用的函数。
BOOL CProp1::OnSetActive() 
{
	// TODO: Add your specialized code here and/or call the base class
	((CPropSheet *)GetParent())->SetWizardButtons(PSWIZB_NEXT);
	return CPropertyPage::OnSetActive();
}
BOOL CProp2::OnSetActive() 
{
	// TODO: Add your specialized code here and/or call the base class
	((CPropSheet *)GetParent())->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
	return CPropertyPage::OnSetActive();
}
BOOL CProp3::OnSetActive() 
{
	// TODO: Add your specialized code here and/or call the base class
	((CPropSheet *)GetParent())->SetWizardButtons(PSWIZB_BACK | PSWIZB_FINISH);
	return CPropertyPage::OnSetActive();
}
向导中,没有进行选择,则不能进入到下一步中 功能的实现:
在第一个属性页相对应的类中,用ClassWizard重载一个OnWizardNext()虚函数。
对单选按钮该功能的实现:
1、	在该属性页的资源中,将单选框的第一个按钮的属性的Group勾选上,以表示这些单选按钮是一组。
2、	再通过ClassWizard为第一个按钮添加一个数据变量m_occupation,则在构造函数中,该值被初始化为-1,表示该单选按钮没有项被选上。如果该组单选按钮被选中,则该组单选按钮是以0开始的,依次往下编号。
3、	OnWizardNext()函数如下:
LRESULT CProp1::OnWizardNext() 
{
	// TODO: Add your specialized code here and/or call the base class
	UpdateData();//这个函数是必须的,表示要从控件中取值。
	if(m_occupation==-1)
	{
		MessageBox("请选择你的职业!");
		return -1;//必须得返回-1,表示不能进入到下一步。
	}
	return CPropertyPage::OnWizardNext();
}
对列表框的该功能的实现:
1、	列表框元素的添加:
在第一个属性页中,用ClassWizard添加一个命令响应函数,并在其中添加语句,如下:
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
}
2、	通过ClassWizard对该列表框添加一个字符串型的数值变量:m_wordPlace,该值初始化为空。
3、	在OnWizardNext()函数如下:
LRESULT CProp1::OnWizardNext() 
{
	// TODO: Add your specialized code here and/or call the base class
	UpdateData();
	if(m_occupation==-1)
	{
		MessageBox("请选择你的职业!");
		return -1;
	}
	if(m_workPlace=="")
	{
		MessageBox("请选择你的工作地点!");
		return -1;
	}
	return CPropertyPage::OnWizardNext();
}
对复选框该功能的实现:
1、	通过ClassWizard为每一个复选框的项添加一个布尔型的数值变量,该变量在构造函数中,都被初始化为FALSE。
2、	在OnWizardNext()中如下编辑:
LRESULT CProp2::OnWizardNext() 
{
	// TODO: Add your specialized code here and/or call the base class
	UpdateData();
	if(	m_basketball||m_pingpang||m_swimming||m_dance||m_football)
	{
		return CPropertyPage::OnWizardNext();
	}
	else
	{
		MessageBox("请选择你的兴趣爱好!");
		return -1;
	}
}
组合框中的元素添加:
在OnInitDialog()中如下操作:
BOOL CProp3::OnInitDialog() 
{
	CPropertyPage::OnInitDialog();
	
	// TODO: Add extra initialization here
	((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("1000元以下");
	((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("1000—2000元");
	((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("2000—3000元");
	((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("3000—4000元");
	((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("4000元以上");
	((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
}
获得组合框中列表框中的内容:
在组合框所在的属性页上添加一个字符串型的公有变量CString  m_strSalary,然后在该属性页上重载一个虚函数OnWizardFinish()如下:
BOOL CProp3::OnWizardFinish() 
{
	// TODO: Add your specialized code here and/or call the base class
	int index;
	index=((CComboBox *)GetDlgItem(IDC_COMBO1))->GetCurSel();
//获得组合框中元素的索引号,索引号是基于0的
	((CComboBox *)GetDlgItem(IDC_COMBO1))->GetLBText(index,m_strSalary);
//将相应索引号所对应的文本信息,复制到m_strSalary中。
	return CPropertyPage::OnWizardFinish();
}
最后一个属性页的完成按钮上,实现的功能:(将每一步所选选项,全部输出在单文档上)
1、	在CPropView类中,添加如下私有变量:
	int m_iOccupation;//接收职业的索引号
	CString m_strWorkPlace;//接收工作地点
	BOOL m_bLike[5];//用一个布尔型的数组接收复选框里的兴趣爱好
	CString m_strSalary;//接收工资水平
2、	在菜单栏的子菜单的菜单项的响应函数中,添加如下语句:
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_strWorkPlace=PropSheet.m_prop1.m_workPlace;
		m_bLike[0]=PropSheet.m_prop2.m_basketball;
		m_bLike[1]=PropSheet.m_prop2.m_dance;
		m_bLike[2]=PropSheet.m_prop2.m_football;
		m_bLike[3]=PropSheet.m_prop2.m_pingpang;
		m_bLike[4]=PropSheet.m_prop2.m_swimming;
		m_strSalary=PropSheet.m_prop3.m_strSalary;
		Invalidate();
	}
}
3、	在CPropView类的OnDraw()函数中添加如下语句:
void CPropView::OnDraw(CDC* pDC)
{
	CPropDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	CString strTemp;
	strTemp="你的职业:";
	switch(m_iOccupation)
	{
	case 0:
		strTemp+="程序员";
		break;
	case 1:
		strTemp+="系统架构师";
		break;
	case 2:
		strTemp+="项目经理";
		break;
	default:
		break;
	}
	pDC->TextOut(0,0,strTemp);
	strTemp="你的工作地点:";
	strTemp+=m_strWorkPlace;
	TEXTMETRIC tm;
	pDC->GetTextMetrics(&tm);
	pDC->TextOut(0,tm.tmHeight,strTemp);
	strTemp="你的兴趣爱好:";
	if(m_bLike[0])
		strTemp+="篮球 ";
	if(m_bLike[1])
		strTemp+="跳舞 ";
	if(m_bLike[2])
		strTemp+="足球 ";
	if(m_bLike[3])
		strTemp+="乒乓球 ";
	if(m_bLike[4])
		strTemp+="游泳 ";
	pDC->TextOut(0,tm.tmHeight*2,strTemp);
	strTemp="你的工资水平:";
	strTemp+=m_strSalary;
	pDC->TextOut(0,tm.tmHeight*3,strTemp);
	
}