当前位置: 代码迷 >> 综合 >> 孙鑫VC++深入详解:Lesson8 Part2---属性表单
  详细解决方案

孙鑫VC++深入详解:Lesson8 Part2---属性表单

热度:18   发布时间:2024-01-19 15:16:18.0


1. Insert-->Dialog 插入IDD_LARGER...Page....3个   Style:Child, Disable 

    注意:修改Page的语言属性(不是字体)必须只能在Resource View中选Dialog单独选IDD_PROP1的右键属性,而不是在资源编辑器中选择右键的属性(那里只能选择字体).

2 分别给三个属性表单页Page1,Page2,Page3 用ClassWizard创建3个类,CPage1,CPage2,CPage3

3. 属性表单页CPropertyPage实际是要附加在CPropertySheet上才能显示

   (1)CPropertyPage必须加载到CPropertySheet

  (2) Sheet调用DoModal去创建表单sheet,这样才能把3个page显示

4 Insert--New class 创建一个新的基于CPropertySheet的类,用来操作3个Page,这个新类叫CPropSheet

5. 向导模式 SetWizardMode

6 SetWizardButtons 解决sheet上buttons显示的问题:

       要在CPage1中覆盖基类的OnSetActive() 的实现代码中解决Sheet的WizardButtons问题,为什么不直接在CPropSheet中解决?

7 在View视中定义一个CPropSheet propSheet变量,用propSheet来操作Page1,Page2,Page3


//---------CPage1类的实现

  头文件Page1.h

#if !defined(AFX_PAGE1_H__2430209C_79B9_43D5_AB82_3ADD0B3D1AA8__INCLUDED_)
#define AFX_PAGE1_H__2430209C_79B9_43D5_AB82_3ADD0B3D1AA8__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Page1.h : header file
///
// CPage1 dialogclass CPage1 : public CPropertyPage
{DECLARE_DYNCREATE(CPage1)// Construction
public:CPage1();~CPage1();// Dialog Data//{
   {AFX_DATA(CPage1)enum { IDD = IDD_PROP1 };int		m_occupation;CString	m_workAddr;//}}AFX_DATA// Overrides// ClassWizard generate virtual function overrides//{
   {AFX_VIRTUAL(CPage1)public:virtual BOOL OnSetActive();virtual LRESULT OnWizardNext();protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support//}}AFX_VIRTUAL// Implementation
protected:// Generated message map functions//{
   {AFX_MSG(CPage1)virtual BOOL OnInitDialog();//}}AFX_MSGDECLARE_MESSAGE_MAP()};//{
   {AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_PAGE1_H__2430209C_79B9_43D5_AB82_3ADD0B3D1AA8__INCLUDED_)

类成员实现:Page1.cpp

// Page1.cpp : implementation file
//#include "stdafx.h"
#include "prop.h"
#include "Page1.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/
// CPage1 property pageIMPLEMENT_DYNCREATE(CPage1, CPropertyPage)CPage1::CPage1() : CPropertyPage(CPage1::IDD)
{//{
   {AFX_DATA_INIT(CPage1)m_occupation = -1; m_workAddr = _T("");//}}AFX_DATA_INIT
}CPage1::~CPage1()
{
}void CPage1::DoDataExchange(CDataExchange* pDX)
{CPropertyPage::DoDataExchange(pDX);//{
   {AFX_DATA_MAP(CPage1)DDX_Radio(pDX, IDC_RADIO1, m_occupation);DDX_LBString(pDX, IDC_LIST1, m_workAddr);//}}AFX_DATA_MAP
}BEGIN_MESSAGE_MAP(CPage1, CPropertyPage)//{
   {AFX_MSG_MAP(CPage1)//}}AFX_MSG_MAP
END_MESSAGE_MAP()/
// CPage1 message handlers// 覆盖基类的虚函数:设置sheet上哪个WiZard button 要显示
BOOL CPage1::OnSetActive() 
{// TODO: Add your specialized code here and/or call the base class((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_NEXT);return CPropertyPage::OnSetActive();
}// 覆盖基类的虚函数:在点击"next"按钮前,获得m_occupation的值
LRESULT CPage1::OnWizardNext() 
{// TODO: Add your specialized code here and/or call the base classUpdateData(true); if(m_occupation==-1){MessageBox("请选择你的职业");return -1;}	if(m_workAddr==""){MessageBox("请选择你的工作地点");return -1;}return CPropertyPage::OnWizardNext();
}// 这个消息是CPage在显示之前发送的.
BOOL CPage1::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
}


//------CPage2类的实现

    头文件Page2.h

  

#if !defined(AFX_PAGE2_H__58B69281_180E_4981_A868_2AED621B7D48__INCLUDED_)
#define AFX_PAGE2_H__58B69281_180E_4981_A868_2AED621B7D48__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Page2.h : header file
///
// CPage2 dialogclass CPage2 : public CPropertyPage
{DECLARE_DYNCREATE(CPage2)// Construction
public:CPage2();~CPage2();// Dialog Data//{
   {AFX_DATA(CPage2)enum { IDD = IDD_PROP2 };BOOL	m_football;BOOL	m_basketball;BOOL	m_volleyball;BOOL	m_swim;//}}AFX_DATA// Overrides// ClassWizard generate virtual function overrides//{
   {AFX_VIRTUAL(CPage2)public:virtual BOOL OnSetActive();virtual LRESULT OnWizardNext();protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support//}}AFX_VIRTUAL// Implementation
protected:// Generated message map functions//{
   {AFX_MSG(CPage2)// NOTE: the ClassWizard will add member functions here//}}AFX_MSGDECLARE_MESSAGE_MAP()};//{
   {AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_PAGE2_H__58B69281_180E_4981_A868_2AED621B7D48__INCLUDED_)

 类的实现 Page2.cpp

// Page2.cpp : implementation file
//#include "stdafx.h"
#include "prop.h"
#include "Page2.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/
// CPage2 property pageIMPLEMENT_DYNCREATE(CPage2, CPropertyPage)CPage2::CPage2() : CPropertyPage(CPage2::IDD)
{//{
   {AFX_DATA_INIT(CPage2)m_football = FALSE;m_basketball = FALSE;m_volleyball = FALSE;m_swim = FALSE;//}}AFX_DATA_INIT
}CPage2::~CPage2()
{
}void CPage2::DoDataExchange(CDataExchange* pDX)
{CPropertyPage::DoDataExchange(pDX);//{
   {AFX_DATA_MAP(CPage2)DDX_Check(pDX, IDC_CHECK1, m_football);DDX_Check(pDX, IDC_CHECK2, m_basketball);DDX_Check(pDX, IDC_CHECK3, m_volleyball);DDX_Check(pDX, IDC_CHECK4, m_swim);//}}AFX_DATA_MAP
}BEGIN_MESSAGE_MAP(CPage2, CPropertyPage)//{
   {AFX_MSG_MAP(CPage2)// NOTE: the ClassWizard will add message map macros here//}}AFX_MSG_MAP
END_MESSAGE_MAP()/
// CPage2 message handlersBOOL CPage2::OnSetActive() 
{// TODO: Add your specialized code here and/or call the base class((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK|PSWIZB_NEXT);return CPropertyPage::OnSetActive();
}LRESULT CPage2::OnWizardNext() 
{// TODO: Add your specialized code here and/or call the base classUpdateData(true);// 取得控件关联的值if(m_football||m_basketball||m_volleyball||m_swim)	{return CPropertyPage::OnWizardNext();}else{MessageBox("请选择你的兴趣爱好");return -1;}
}

//---CPage3 类的实现

 头文件Page3.h

#if !defined(AFX_PAGE3_H__BFD081AC_E2AB_4685_A974_1FB0B946D8F7__INCLUDED_)
#define AFX_PAGE3_H__BFD081AC_E2AB_4685_A974_1FB0B946D8F7__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Page3.h : header file
///
// CPage3 dialogclass CPage3 : public CPropertyPage
{DECLARE_DYNCREATE(CPage3)// Construction
public:CString m_strSalary;CPage3();~CPage3();// Dialog Data//{
   {AFX_DATA(CPage3)enum { IDD = IDD_PROP3 };// NOTE - ClassWizard will add data members here.//    DO NOT EDIT what you see in these blocks of generated code !//}}AFX_DATA// Overrides// ClassWizard generate virtual function overrides//{
   {AFX_VIRTUAL(CPage3)public:virtual BOOL OnSetActive();virtual BOOL OnWizardFinish();protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support//}}AFX_VIRTUAL// Implementation
protected:// Generated message map functions//{
   {AFX_MSG(CPage3)virtual BOOL OnInitDialog();//}}AFX_MSGDECLARE_MESSAGE_MAP()};//{
   {AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_PAGE3_H__BFD081AC_E2AB_4685_A974_1FB0B946D8F7__INCLUDED_)

 类的实现:Page3.cpp

// Page3.cpp : implementation file
//#include "stdafx.h"
#include "prop.h"
#include "Page3.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/
// CPage3 property pageIMPLEMENT_DYNCREATE(CPage3, CPropertyPage)CPage3::CPage3() : CPropertyPage(CPage3::IDD)
{//{
   {AFX_DATA_INIT(CPage3)// NOTE: the ClassWizard will add member initialization here//}}AFX_DATA_INIT
}CPage3::~CPage3()
{
}void CPage3::DoDataExchange(CDataExchange* pDX)
{CPropertyPage::DoDataExchange(pDX);//{
   {AFX_DATA_MAP(CPage3)// NOTE: the ClassWizard will add DDX and DDV calls here//}}AFX_DATA_MAP
}BEGIN_MESSAGE_MAP(CPage3, CPropertyPage)//{
   {AFX_MSG_MAP(CPage3)//}}AFX_MSG_MAP
END_MESSAGE_MAP()/
// CPage3 message handlersBOOL CPage3::OnSetActive() 
{// TODO: Add your specialized code here and/or call the base class((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT| PSWIZB_FINISH);	return CPropertyPage::OnSetActive();
}BOOL CPage3::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元以上");((CComboBox*)GetDlgItem(IDC_COMBO1))->SetCurSel(0); //设置默认选项 1000元以下return TRUE;  // return TRUE unless you set the focus to a control// EXCEPTION: OCX Property Pages should return FALSE
}// 在点击 finish按钮时,获得用户薪资的选择
BOOL CPage3::OnWizardFinish() 
{// TODO: Add your specialized code here and/or call the base classint index;index =	((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCurSel(); ((CComboBox*)GetDlgItem(IDC_COMBO1))->GetLBText(index,m_strSalary);return CPropertyPage::OnWizardFinish();
}

//------类CPropSheet : public CPropertySheet 的实现

头文件

#if !defined(AFX_PROPSHEET_H__1B859A0A_9314_4803_A031_F70427A6925A__INCLUDED_)
#define AFX_PROPSHEET_H__1B859A0A_9314_4803_A031_F70427A6925A__INCLUDED_#include "Page2.h"	// Added by ClassView
#include "Page1.h"	// Added by ClassView
#include "Page3.h"	// Added by ClassView
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// PropSheet.h : header file
///
// CPropSheetclass CPropSheet : public CPropertySheet
{DECLARE_DYNAMIC(CPropSheet)// Construction
public:CPropSheet(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);CPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);// Attributes
public:// Operations
public:// Overrides// ClassWizard generated virtual function overrides//{
   {AFX_VIRTUAL(CPropSheet)//}}AFX_VIRTUAL// Implementation
public:CPage3 m_Page3;CPage2 m_Page2;CPage1 m_Page1;virtual ~CPropSheet();// Generated message map functions
protected://{
   {AFX_MSG(CPropSheet)// NOTE - the ClassWizard will add and remove member functions here.//}}AFX_MSGDECLARE_MESSAGE_MAP()
};///{
   {AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_PROPSHEET_H__1B859A0A_9314_4803_A031_F70427A6925A__INCLUDED_)

实现:

// PropSheet.cpp : implementation file
//#include "stdafx.h"
#include "Prop.h"
#include "PropSheet.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/
// CPropSheetIMPLEMENT_DYNAMIC(CPropSheet, CPropertySheet)//在2个构造函数中加载page
CPropSheet::CPropSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage):CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
{// 加载pageAddPage(&m_Page1);AddPage(&m_Page2);AddPage(&m_Page3);	
//	SetWizardMode(); // 这条语句的作于就是把page搞成向导模式
}CPropSheet::CPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage):CPropertySheet(pszCaption, pParentWnd, iSelectPage)
{// 加载pageAddPage(&m_Page1);AddPage(&m_Page2);AddPage(&m_Page3);	
//	SetWizardMode();
}CPropSheet::~CPropSheet()
{
}BEGIN_MESSAGE_MAP(CPropSheet, CPropertySheet)//{
   {AFX_MSG_MAP(CPropSheet)// NOTE - the ClassWizard will add and remove mapping macros here.//}}AFX_MSG_MAP
END_MESSAGE_MAP()/
// CPropSheet message handlers


在程序的View视中实现输出:

 头文件CPropView.h

// PropView.h : interface of the CPropView class
//
/#if !defined(AFX_PROPVIEW_H__F5F57441_99E9_4B4C_9F3A_E41E7646095E__INCLUDED_)
#define AFX_PROPVIEW_H__F5F57441_99E9_4B4C_9F3A_E41E7646095E__INCLUDED_#include "Page1.h"	// Added by ClassView 
#include "Page2.h"	// Added by ClassView
#include "Page3.h"	// Added by ClassView
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000class CPropView : public CView
{
protected: // create from serialization onlyCPropView();DECLARE_DYNCREATE(CPropView)// Attributes
public:CPropDoc* GetDocument();// Operations
public:// Overrides// ClassWizard generated virtual function overrides//{
   {AFX_VIRTUAL(CPropView)public:virtual void OnDraw(CDC* pDC);  // overridden to draw this viewvirtual BOOL PreCreateWindow(CREATESTRUCT& cs);protected://}}AFX_VIRTUAL// Implementation
public:virtual ~CPropView();
#ifdef _DEBUGvirtual void AssertValid() const;virtual void Dump(CDumpContext& dc) const;
#endifprotected:// Generated message map functions
protected://{
   {AFX_MSG(CPropView)afx_msg void OnPropertysheet();//}}AFX_MSGDECLARE_MESSAGE_MAP()private:int m_iOccupation;CString m_strWorkAddr;BOOL bLike[4];CString m_strSalary;
};#ifndef _DEBUG  // debug version in PropView.cpp
inline CPropDoc* CPropView::GetDocument(){ return (CPropDoc*)m_pDocument; }
#endif///{
   {AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_PROPVIEW_H__F5F57441_99E9_4B4C_9F3A_E41E7646095E__INCLUDED_)

实现:

// PropView.cpp : implementation of the CPropView class
//#include "stdafx.h"
#include "Prop.h"#include "PropDoc.h"
#include "PropView.h"#include "PropSheet.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/
// CPropViewIMPLEMENT_DYNCREATE(CPropView, CView)BEGIN_MESSAGE_MAP(CPropView, CView)//{
   {AFX_MSG_MAP(CPropView)ON_COMMAND(IDM_PROPERTYSHEET, OnPropertysheet)//}}AFX_MSG_MAP
END_MESSAGE_MAP()/
// CPropView construction/destructionCPropView::CPropView()
{// TODO: add construction code herem_iOccupation=-1;m_strWorkAddr="";memset(bLike,0,sizeof(bLike));m_strSalary="";}CPropView::~CPropView()
{
}BOOL CPropView::PreCreateWindow(CREATESTRUCT& cs)
{// TODO: Modify the Window class or styles here by modifying//  the CREATESTRUCT csreturn CView::PreCreateWindow(cs);
}/
// CPropView drawingvoid CPropView::OnDraw(CDC* pDC)
{CPropDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereCFont font;font.CreatePointFont(300,"华文楷体");CFont *pOldPen;pOldPen = pDC->SelectObject(&font);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_strWorkAddr;TEXTMETRIC tm;pDC->GetTextMetrics(&tm);pDC->TextOut(0,tm.tmHeight,strTemp);strTemp = "你的兴趣爱好: ";if(bLike[0])strTemp +="足球";if(bLike[1])strTemp +="篮球";if(bLike[2])strTemp +="排球";if(bLike[3])strTemp +="游泳";pDC->TextOut(0,tm.tmHeight*2,strTemp);strTemp = "你的薪资水平: ";strTemp +=m_strSalary;pDC->TextOut(0,tm.tmHeight*3,strTemp);	pDC->SelectObject(pOldPen);}/
// CPropView diagnostics#ifdef _DEBUG
void CPropView::AssertValid() const
{CView::AssertValid();
}void CPropView::Dump(CDumpContext& dc) const
{CView::Dump(dc);
}CPropDoc* CPropView::GetDocument() // non-debug version is inline
{ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPropDoc)));return (CPropDoc*)m_pDocument;
}
#endif //_DEBUG/
// CPropView message handlersvoid CPropView::OnPropertysheet() 
{// TODO: Add your command handler code hereCPropSheet propSheet("微信属性表单程序"); //创建一个CPropSheet对象	// 表单要显示,还必须调用domodal或者createpropSheet.SetWizardMode(); //设置成向导模式//创建一个模态的对话框	if(ID_WIZFINISH ==propSheet.DoModal())				{m_iOccupation = propSheet.m_Page1.m_occupation;m_strWorkAddr = propSheet.m_Page1.m_workAddr;bLike[0]= propSheet.m_Page2.m_football;bLike[1]= propSheet.m_Page2.m_basketball;bLike[2]= propSheet.m_Page2.m_volleyball;bLike[3]= propSheet.m_Page2.m_swim;	m_strSalary = propSheet.m_Page3.m_strSalary;Invalidate();}}


//---


//---

//---


总体感觉VC做这种向导属性表单非常繁琐....远不如Delphi的结构清晰.

 


  相关解决方案