您的位置:首页 > 编程语言 > C语言/C++

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

2013-07-09 19:58 501 查看
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的结构清晰.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐