对话框
一、“你能抓到我吗?”小游戏:
①创建一个新的对话框工程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);
}