VC学习笔记:属性表单与向导
SkySeraph NOV.9th 2010 HQU
Email-zgzhaobo@gmail.com QQ-452728574
Latest Modified Date:NOV.9th 2010 HQU
0 前
一个属性表单由一/多个属性页组成
CPropertyPage() | 派生于CWnd类-CCmdTarget-CObject |
|
CPropertySheet() | 派生于CDIalog类-CWnd-CCmdTarget-CObject |
|
1 创建属性页
① 插入三个属性页资源IDD_PROPERTYPAGE_LARGE,ID分别为IDD_PROP1/2/3,Caption分别为Page1/2/3。 区别插入属性页和对话框。
② 完成属性页表单的建立
属性页1 | 三个单选按钮用户职业选择、一个列表框用户地点选择 |
|
属性页2 | 四个多选框表示用户兴趣选择 |
|
属性页3 | 一个组合框表示薪资水平选择 | 大小调整技巧;sort属性默认选上,去掉后组合框列表的字符串按添加顺序排列 |
③ 为三个属性页资源关联属性页类CProp1/2/3,基类都为CPropertyPage
2 创建属性表单
思路:创建一个CPropertySheet对象、在此对象中为每个属性页创建一个CPropertyPage对象、调用AddPage函数添加每一个属性页、调用DoModule/Create显示/创建模态/非模态属性表单
① 创建属性表单对象:新建类CPropSheet,以CPropertySheet为基类
② 在属性表单类CPropSheet的头文件中添加属性页,代码如下:[有两个构造函数,都添加]
CPropSheet::CPropSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
:CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
{
AddPage(&m_prop1);
AddPage(&m_prop2);
AddPage(&m_prop3);
}
CPropSheet::CPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
:CPropertySheet(pszCaption, pParentWnd, iSelectPage)
{
AddPage(&m_prop1);
AddPage(&m_prop2);
AddPage(&m_prop3);
}
需在属性表单类头文件中包含
#include "Prop1.h"
#include "Prop2.h"
#include "Prop3.h"
③ 显示属性表单:添加菜单项IDM_PROPERTYSHEET及消息响应函数[View类]并在View头文件包含属性表单类头文件,再添加代码:
void CTest_DlgView::OnPropertysheet()
{
CPropSheet propsheet("属性表单");
propsheet.DoModal();
}
3 创建向导
① 创建向导:
void CTest_DlgView::OnPropertysheet()
{
CPropSheet propsheet("属性表单");
propsheet.SetWizardMode(); //将属性页改为向导式
/*但,由于向导式有“上一步”“下一步”“完成”等类型特殊的按钮。因此需要分别在代表3个属性页的类中为其修改相应的值,以保证在第一页不出现上一步,最后一页以完成告终。*/
propsheet.DoModal();
}
② 改进:向导对话框上的按钮的修改
向导对话框上按钮的修改 | CPropertySheet类提供的SetWizardButtons |
SetWizardButtons函数调用 | 一般,属性页要再虚函数OnSetActive中调用SetWizardButtons,在三个属性页中都重写该虚函数 |
代码:
BOOL CProp1::OnSetActive()
{
((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_NEXT);
//void SetWizardButtons(DWORD dwFlags );Enables or disables the Back, Next, or Finish button in a wizard property sheet.
return CPropertyPage::OnSetActive();
}
BOOL CProp2::OnSetActive()
{
((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK|PSWIZB_NEXT);
return CPropertyPage::OnSetActive();
}
BOOL CProp3::OnSetActive()
{
((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK|PSWIZB_FINISH);
return CPropertyPage::OnSetActive();
}
4 属性页处理
4.1 第一个页面:
① 为属性页1单选按钮控件 关联变量m_Occupation [value类别、int类型],并再其构造函数中初始化为-1 。属性页1的第一个单选按钮需勾选上Group!
② 重写虚函数OnWizardNext用来处理属性页下一步按钮响应。该函数返回0进入下一步,返回-1则禁止属性页发生变化
LRESULT CProp1::OnWizardNext()
{
UpdateData();//控件与成员变量的数据交换通过DoDateExchange,程序不直接调用此函数,需要通过UpdateData来调用它
if(m_Occupation ==-1)
{
MessageBox("Please input your carrer!");
return -1;
}
return CPropertyPage::OnWizardNext();
}
③ 列表框工作地点的判断:首先需要在属性页显示之前向列表框添加一些地点/资源,在WM_INITDIALOG中完成
BOOL CProp1::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: 在此添加额外的初始化
((CListBox*)GetDlgItem(IDC_LIST1))->AddString("Shang Hai");
((CListBox*)GetDlgItem(IDC_LIST1))->AddString("BeiJing");
((CListBox*)GetDlgItem(IDC_LIST1))->AddString("XiaMen");
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
④ 为列表框控件管理变量m_workWork[value类别、CString类型],并在其构造函数中初始化为_T(" "),再修改②
LRESULT CProp1::OnWizardNext()
{
UpdateData();//控件与成员变量的数据交换通过DoDateExchange,程序不直接调用此函数,需要通过UpdateData来调用它
if(m_Occupation ==-1)
{
MessageBox("Please input your carrer!");
return -1;
}
if(m_WorkAddr =="")
{
MessageBox("Please Choose your city!");
return -1;
}
return CPropertyPage::OnWizardNext();
}
4.2 第二个页面:
① 为四个多选控件分别关联变量:BOOL型,m_Basketrball、m_Music、m_Billards、m_Dance
② 重写虚函数OnWizardNext用来处理属性页下一步按钮响应。
LRESULT CProp2::OnWizardNext()
{
// TODO: 在此添加专用代码和/或调用基类
UpdateData();
if(m_Dance||m_Billards||m_Basketrball||m_Music)
{
return CPropertyPage::OnWizardNext(); //灵活性
}
else
{
MessageBox("Please Choose your Interests!");
return -1;
}
}
4.3 第三个页面:
① 为组合框控件添加资源,同4.2 ③,代码:
BOOL CProp3::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: 在此添加额外的初始化
((CComboBox*)GetDlgItem(IDC_COMBO2))->SetCurSel(0); //初始选项
((CComboBox*)GetDlgItem(IDC_COMBO2))->AddString("<=5000");
((CComboBox*)GetDlgItem(IDC_COMBO2))->AddString("5000~8000");
((CComboBox*)GetDlgItem(IDC_COMBO2))->AddString("8000~12000");
((CComboBox*)GetDlgItem(IDC_COMBO2))->AddString(">12000");
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
② 取消Sort属性
5 接受用户向导中所做的选择
5.1 第三个属性页处理
① 为第三个属性页添加成员变量m_strSalary,CString类型
② 重写OnWizardFinish函数
BOOL CProp3::OnWizardFinish()
{
// TODO: 在此添加专用代码和/或调用基类
int index;
index = ((CComboBox*)GetDlgItem(IDC_COMBO2))->GetCurSel();//获得索引值
((CComboBox*)GetDlgItem(IDC_COMBO2))->GetLBText(index,m_strSalary);//从组合框指定位置获得一个字符串
return CPropertyPage::OnWizardFinish();
}
5.2 视类处理
① 为接受用户向导中的选择,为视类添加成员变量:
在其构造函数中初始化:
m_iOccupation =-1;
m_strWorkAddr = " ";
m_strSalary = " ";
memset(m_bLike,0,sizeof(m_bLike));
② 把用户向导选择输出到窗口
void CTest_DlgView::OnPropertysheet()
{
CPropSheet propsheet("属性表单");
propsheet.SetWizardMode(); //将属性页改为向导式
/*但,由于向导式有“上一步”“下一步”“完成”等类型特殊的按钮。因此
需要分别在代表3个属性页的类中为其修改相应的值,以保证在第一页不出现上一步,最后一页以完成告终。*/
//propsheet.DoModal();
if(ID_WIZFINISH==propsheet.DoModal())
//一般情况下,CpropertySheet类的DoModal函数返回值是IDOK或IDCANCEL,但是若属性表单已经被创建为向导了,则返回值为ID_WIZFINISH或IDCANCEL
{
m_iOccupation = propsheet.m_prop1.m_Occupation;
m_strWorkAddr = propsheet.m_prop1.m_WorkAddr;
m_bLike[0] = propsheet.m_prop2.m_Music;
m_bLike[1] = propsheet.m_prop2.m_Basketrball;
m_bLike[2] = propsheet.m_prop2.m_Billards;
m_bLike[3] = propsheet.m_prop2.m_Dance;
m_strSalary = propsheet.m_prop3.m_strSalary;
Invalidate();//让视图无效,引起重绘操作,自动调用OnDraw
}
}
③ OnDraw中 完成输出
void CTest_DlgView::OnDraw(CDC* /*pDC*/)
{
CTest_DlgDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
CClientDC dc(this);//取得客户区内存DC
CFont font;
font.CreatePointFont(300,"华文行楷");
CFont *pOldFont;
pOldFont=dc.SelectObject(&font);
CString strTemp;
strTemp="你的职业:";
switch(m_iOccupation)
{
case 0:
strTemp+="工程师";
break;
case 1:
strTemp+="CEO";
break;
case 2:
strTemp+="CTO";
break;
default:
break;
}
dc.TextOut(0,0,strTemp);
strTemp="你的工作地点:";
strTemp+=m_strWorkAddr;
TEXTMETRIC tm;
dc.GetTextMetrics(&tm);//得到当前文本高度
dc.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+="舞蹈 ";
}
dc.TextOut(0,tm.tmHeight*2,strTemp);
strTemp="你的薪资水平:";
strTemp+=m_strSalary;
dc.TextOut(0,tm.tmHeight*3,strTemp);
dc.SelectObject(pOldFont);
}
Author: SKySeraph
Email/GTalk: zgzhaobo@gmail.com QQ:452728574
From: http://www.cnblogs.com/skyseraph/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,请尊重作者的劳动成果。