VC++/MFC Window编程原创教程目录
1:设置一个属性表单
添加三个Dialog--IDD_PROPPAGE_LARGE资源,修改ID为:IDD_PROP1、2、3;
添加如下控件:
右键点击IDD_PROP1、2、3资源视图--添加类(类名CProp1、2、3,基类:CPropertyPage属性页类);
添加新类CPropSheet,基类为:CPropertySheet。一个属性表由一个CPropertySheet对象和一个或多个CPropertyPage对象构成。
为CPropSheet添加CProp1、2、3变量m_prop1、2、3。
在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);
}
最后在菜单增加子菜单(属性表单),改其ID为IDM_PROPERTYSHEET,添加CPropView下的COMMAND消息。代码:
void CPropView::OnPropertysheet()
{
// TODO: 在此添加命令处理程序代码
CPropSheet propSheet("属性表单程序");
propSheet.SetWizardMode(); //加上此句代码表向导模式。不加,则是选择模式。
propSheet.DoModal(); //显示方法与Dialog相似
}
若使用向导模式,则需增加代码完善页面。
CProp1--属性--重写(虚函数)--添加OnSetActive() //选择的页面为活动页面时触发的函数。代码如下
BOOL CProp1::OnSetActive()
{
// TODO: 在此添加专用代码和/或调用基类
((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_NEXT); //属性表单是属性页的父窗口,所以可以使用GetParent()获取然后进行转换。SetWizardButtons(PSWIZB_NEXT)表向导第一页只有下一步可用。
//同理,在CProp2、3添加的OnSetActive()代码为:
((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK | PSWIZB_FINISH);
return CPropertyPage::OnSetActive();
}
2.1:需要进行选择职业才能进入下一步。
将单选选项的Group属性值设置为TRUE才能为选项关联变量,表该页的单选选项关联在同一组,下标为0、1、2...直到遇到下个单选选项的Group属性值为TRUE的另一组。
为"程序员IDC_RADIO1"关联变量(Value,int变量名m_occupation),在构造函数将其初始值设为-1(0的话表默认选择第一项了)。然后重写(虚函数)OnWizardNext,代码:
LRESULT CProp1::OnWizardNext()
{
// TODO: 在此添加专用代码和/或调用基类
UpdateData(); //DoDataExchange 框架与控件用来交流数据,呼叫UpdateData函数时才会被调用http://zhidao.baidu.com/question/89105522.html
if(m_occupation==-1)
{
MessageBox("请选择你的职业");
return -1; //返回-1表返回当前属性页;返回0表下一步
}
return CPropertyPage::OnWizardNext();
}
2.2:需要进行选择工作地点才能进入下一步。
为IDC_LIST1列表框关联一个变量(Value,CString,变量名m_workAddr)。
重写(虚函数)OnInitDialog (框架显示前响应),代码:
BOOL CProp1::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: 在此添加额外的初始化
((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
// 异常: OCX 属性页应返回 FALSE
}
2.3:第二页,需要选择兴趣爱好才能下一步。
为IDC_CHECK1、2、3、4分别添加变量m_football、m_basketball、m_volleyball、m_swin(Value,BOOL)
为CProp2重写nWizardNext
LRESULT CProp2::OnWizardNext()
{
// TODO: 在此添加专用代码和/或调用基类
UpdateData();
if(m_football || m_basketball || m_volleyball || m_swin)
{
return CPropertyPage::OnWizardNext();
}
else
{
MessageBox("请选择你的兴趣爱好");
return -1;
}
}
2.4:第三页,默认选择第一项。
重写(虚函数)OnInitDialog
BOOL CProp3::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: 在此添加额外的初始化
((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); //选择第一个(-1为不选择)。
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
3:输出选项内容。
首先在CProp3定义一个CString m_strSalary变量接收选项内容。
为CProp3重写nWizardFinish。
BOOL CProp3::OnWizardFinish()
{
// TODO: 在此添加专用代码和/或调用基类
int index; //接收索引
index=((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCurSel();
((CComboBox*)GetDlgItem(IDC_COMBO1))->GetLBText(index,m_strSalary); //接收对应索引的文本
return CPropertyPage::OnWizardFinish();
}
在View.h类手动添加变量:
int m_iOccupation; //接收职业
CString m_workAddr; //接收工作地点
BOOL m_bLike[4]; //接收兴趣爱好
CString m_strSalary; //接收工薪水平
初始化:
CPropView::CPropView()
{
// TODO: 在此处添加构造代码
m_iOccupation=-1;
m_workAddr="";
memset(m_bLike,0,sizeof(m_bLike)); //数组初始化。参数(首地址,初始值,数组长度)
m_strSalary="";
}
然后是获取属性页各项的值:
void CPropView::OnPropertysheet()
{
// TODO: 在此添加命令处理程序代码
CPropSheet propSheet("属性表单程序");
propSheet.SetWizardMode();
if(propSheet.DoModal()) //窗口销毁之后。但此时对象还在!
{
m_iOccupation=propSheet.m_prop1.m_occupation;
m_workAddr=propSheet.m_prop1.m_workAddr;
m_bLike[0]=propSheet.m_prop2.m_football;
m_bLike[1]=propSheet.m_prop2.m_basketball;
m_bLike[2]=propSheet.m_prop2.m_volleyball;
m_bLike[3]=propSheet.m_prop2.m_swin;
m_strSalary=propSheet.m_prop3.m_strSalary;
//添加一个BOOL变量初始化为FALSE,用在OnDarw的判断
m_bDraw=TRUE;
Invalidate(); //让窗口无效,引起窗口重绘。然后在OnDraw完成信息是输出
}
}
void CPropView::OnDraw(CDC* pDC) //把后面的注释取消
{
CPropDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
if(m_bDraw==true)
{
CString strTemp; //接收输出的文本。
TEXTMETRIC tm; //接收字体信息
strTemp="你的职位:";
switch(m_iOccupation) //根据单项选择索引赋值
{
case 0:
strTemp+="程序员";
break;
case 1:
strTemp+="系统工程师";
break;
case 2:
strTemp+="项目经理";
break;
default:
break;
}
pDC->TextOutA(0,0,strTemp); //输出职位
pDC->GetTextMetrics(&tm);
strTemp="你的工作地点:"+m_workAddr;
pDC->TextOutA(0,tm.tmHeight,strTemp); //输出工作地点
strTemp="你的兴趣爱好:";
if(m_bLike[0]==true)
strTemp+="足球 ";
if(m_bLike[1]==true)
strTemp+="篮球 ";
if(m_bLike[2]==true)
strTemp+="排球 ";
if(m_bLike[3]==true)
strTemp+="游泳 ";
pDC->TextOutA(0,tm.tmHeight*2,strTemp); //输出兴趣爱好
strTemp="你的薪资:"+m_strSalary;
pDC->TextOutA(0,tm.tmHeight*3,strTemp); //输出薪资
}
}