Windows程序设计__孙鑫C++Lesson8《对话框操作2》

Windows程序设计__孙鑫C++Lesson8《对话框操作2》

本节要点:
1.逃跑按钮(类的子类化思想)
2.属性表单
3.向导wizard创建
//**************************************************************************************************
1.逃跑按钮(类的子类化思想)
(1)创建一个新的CCatchButton类,派生自Button类。
(2)在CCatchButton类中添加成员变量CCatchButton* m_pBtn;添加WM_MOUSEMOVE响应函数,在其中做隐藏自身而显示对方的操作。即  
void CCatchButton::OnMouseMove(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 ShowWindow(SW_HIDE);
 m_pBtn->ShowWindow(SW_SHOW);
 CButton::OnMouseMove(nFlags, point);
}
(3)在对话框中添加两个CCatchButton对象,并在对话框的初始化中让两个button互取对方的地址赋给成员变量m_pBtn,
即   m_btnCatch1.m_pBtn =&m_btnCatch2;m_btnCatch2.m_pBtn=&m_btnCatch1;
2.属性表单
(1)属性页CPropertyPage类
新建属性页 选择IDC_PROPPAGE_LARGE资源生成对话框资源,然后选择基类CPropertyPage属性页类生成新的类。注意语言选项问题。
(2)增加属性页AddPage放在属性表单CPropertySheet的构造函数中

CPropertySheet有两个构造函数,如下:
CPropertySheet( UINT nIDCaption, CWnd *pParentWnd = NULL, UINT iSelectPage = 0 );
CPropertySheet( LPCTSTR pszCaption, CWnd *pParentWnd = NULL, UINT iSelectPage = 0 );
3.向导wizard创建
(1)在调用CPropertySheet对象的DoModal之前调用SetWizardMode方法即可创建一个向导。
(2)设置“上一步、下一步、完成”按钮 在属性页类中重载virtual BOOL OnSetActive()函数,由CPropertySheet::SetWizardButtons函数完成。
(3)组的属性  直到遇到下一个具有组这个属性的控件为止,这些控件均具有同一组的属性。
(4)属性页上的数据获取  控件关联变量  并且在用户选择时作出判断,判断是否作出合理选择,属性页类可以重载虚函数virtual LRESULT OnWizardNext();或者virtual BOOL OnWizardFinish();函数。
(5)属性表单数据在view类显示 通过View类定义成员变量保存属性表单的成员变量。
这里需要注意virtual int DoModal()方法,MSDN的注释为:
Call this member function to display a modal property sheet. The return value corresponds to the ID of the control that closed
the property sheet. After this function returns, the windows corresponding to the property sheet and all the pages will have been destroyed. The objects themselves will still exist. Typically, you will retrieve data from the CPropertyPage objects after DoModal returns IDOK.
意思为:
调用成员函数来显示一个模态的属性表单。这个函数的返回值标识了用来关闭属性表单控件的ID(如IDOK).在这个函数返回后,和属性表单关联的
窗口和属性页将被销毁。(但是)他们本身(属性表单和属性页对象)仍然存在。典型的,当DoModal函数返回IDOK时,你可以从属性页对象获取数据


这再次提醒我们,对象的生存期和窗口不是同步的,注意到这一点非常重要。
向导(包含属性表单)的实验的整个过程及相应代码如下:
step1:
创建属性页 产生三个类
//**************************************************************************************************
class CProp1 : public CPropertyPage
//数据成员
int  m_occupation;
CString m_strWorkPlace;
class CProp2 : public CPropertyPage
//数据成员
 BOOL m_bFootBall;
 BOOL m_bBasketBall;
 BOOL m_bVolleyBall;
 BOOL m_bSwim;
class CProp3 : public CPropertyPage
//数据成员
CString m_strSalary;
//**************************************************************************************************
Step2:
添加属性表单对象 将三个属性页添加进去
//**************************************************************************************************
class CpropSheet : public CPropertySheet
//成员变量
CProp1  m_propPage1;
CProp2  m_propPage2;
CProp3  m_propPage3;
//添加属性页
CpropSheet::CpropSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
 :CPropertySheet(pszCaption, pParentWnd, iSelectPage)
{
 AddPage(&m_propPage1);
 AddPage(&m_propPage2);
 AddPage(&m_propPage3);
}
//**************************************************************************************************
Step3:
以向导形式显示属性表单,同时获取属性表单数据
//**************************************************************************************************
属性页的函数重载和数据初始化,仅以Prop1类为例说明如下:
BOOL CProp1::OnSetActive()
{
 // TODO: Add your specialized code here and/or call the base class
 //设置“下一步”按钮
 CpropSheet* psheet = (CpropSheet*) GetParent();  
    psheet->SetWizardButtons( PSWIZB_NEXT );
 return CPropertyPage::OnSetActive();
}

LRESULT CProp1::OnWizardNext()
{
 // TODO: Add your specialized code here and/or call the base class
 UpdateData();//从控件取回值 
 //对属性页上的控件数据选择判断
 if(-1==m_occupation)
 {
  MessageBox("请选择你的职业");
     return -1;
 }
 if(m_strWorkPlace=="")
    {
  MessageBox("请选择你的工作地点");
     return -1;
 }
 return CPropertyPage::OnWizardNext();
}

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("天津");
 return TRUE;  // return TRUE unless you set the focus to a control
               // EXCEPTION: OCX Property Pages should return FALSE
}
//属性表单的显示 数据获取
void CPropView::OnPropsheet()
{
 // TODO: Add your command handler code here
 CpropSheet PropSheet("属性表单");
 PropSheet.SetWizardMode();
 if(ID_WIZFINISH ==PropSheet.DoModal())//显示属性表单并获取属性表单上的数据
 {
     m_nOccupation=PropSheet.m_propPage1.m_occupation;
  m_strWorkAddr=PropSheet.m_propPage1.m_strWorkPlace;
     m_bLike[0]=PropSheet.m_propPage2.m_bBasketBall;
     m_bLike[1]=PropSheet.m_propPage2.m_bFootBall;
     m_bLike[2]=PropSheet.m_propPage2.m_bSwim;
     m_bLike[3]=PropSheet.m_propPage2.m_bVolleyBall;
     m_strSalary=PropSheet.m_propPage3.m_strSalary;
 }
 Invalidate();//刷新窗口
}
//**************************************************************************************************
Step4:
将向导中获取的数据显示到view类视图中
//**************************************************************************************************
void CPropView::OnDraw(CDC* pDC)
{
 CPropDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 // TODO: add draw code for native data here
 CFont font;
 font.CreatePointFont(300,"华文行楷");
    CFont *pOldFont=pDC->SelectObject(&font);
    CString strTemp;
 //将获取数据显示
 strTemp="你的职业: ";
 //判断职业
 switch(m_nOccupation)
 {
 case 0:
    strTemp+="程序员";
    break;
 case 1:
  strTemp+="系统工程师";
    break;
 case 2:
  strTemp+="项目经理";
    break;
 default:
  break;
 }
 pDC->TextOut(0,0,strTemp);
    strTemp="你的工作地点: ";
 strTemp+=m_strWorkAddr;
 //获取字体信息 计算输出位置
 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+=" 游泳";
    pDC->TextOut(0,2*tm.tmHeight,strTemp);
   
 strTemp="你的薪资水平: ";
    strTemp+=m_strSalary;
    pDC->TextOut(0,3*tm.tmHeight,strTemp);
    pDC->SelectObject(pOldFont);
}
//**************************************************************************************************
向导运行效果如下图所示:


 

本节小结:
1.了解CButton类的子类化 学会从MFC已有类派生自定义的类
2.掌握属性表单的使用,以及利用属性表单制作向导 尤其注意属性表单上控件数据获取和校验(用户选择的判断)
3.理解C++类的生存期和窗口生存期的区别 认识并利用这一点将会在以后程序设计中起到很大的帮助作用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值