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


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 dialog

class 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_MSG
	DECLARE_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 page

IMPLEMENT_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 class
	
	UpdateData(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 dialog

class 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_MSG
	DECLARE_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 page

IMPLEMENT_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 handlers

BOOL 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 class

	UpdateData(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 dialog

class 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_MSG
	DECLARE_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 page

IMPLEMENT_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 handlers

BOOL 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 class
	int 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
//

/
// CPropSheet



class 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_MSG
	DECLARE_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

/
// CPropSheet

IMPLEMENT_DYNAMIC(CPropSheet, CPropertySheet)

//在2个构造函数中加载page
CPropSheet::CPropSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
	:CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
{

	
	// 加载page
	AddPage(&m_Page1);
	AddPage(&m_Page2);
	AddPage(&m_Page3);	
//	SetWizardMode(); // 这条语句的作于就是把page搞成向导模式
}

CPropSheet::CPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
	:CPropertySheet(pszCaption, pParentWnd, iSelectPage)
{
	
	// 加载page
	AddPage(&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 > 1000


class CPropView : public CView
{
protected: // create from serialization only
	CPropView();
	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 view
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	protected:
	//}}AFX_VIRTUAL

// Implementation
public:

	virtual ~CPropView();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
	//{{AFX_MSG(CPropView)
	afx_msg void OnPropertysheet();
	//}}AFX_MSG
	DECLARE_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

/
// CPropView

IMPLEMENT_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/destruction

CPropView::CPropView()
{
	// TODO: add construction code here
    m_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 cs

	return CView::PreCreateWindow(cs);
}

/
// CPropView drawing

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 *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 handlers

void CPropView::OnPropertysheet() 
{
	// TODO: Add your command handler code here
    
	CPropSheet propSheet("微信属性表单程序"); //创建一个CPropSheet对象	

	// 表单要显示,还必须调用domodal或者create
	propSheet.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的结构清晰.

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值