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