程序:单文档应用程序
属性页:3个属性页
一个属性表由一个CPropertySheet对象和一个或多个CPropertyPage对象构成。(这句话先看一遍就行)
创建应用程序,就不说了。说一下新建三个窗体Dialog。
Prop1:三个 radio button和一个listBox
为控件创建关联变量,Radio Button只用对第一个创建,因为属性修改了Group后,会自动对后面两个进行关联:类别为value
还需要对后面的ListBox添加的变量进行初始化。
为CProp1这个类添加虚函数OnInitDialog
函数代码:
BOOL CProp1::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: 在此添加额外的初始化
((CListBox*)GetDlgItem(IDC_WORKADDR))->AddString("北京");
((CListBox*)GetDlgItem(IDC_WORKADDR))->AddString("上海");
((CListBox*)GetDlgItem(IDC_WORKADDR))->AddString("深圳");
((CListBox*)GetDlgItem(IDC_WORKADDR))->AddString("广州");
((CListBox*)GetDlgItem(IDC_WORKADDR))->AddString("成都");
((CListBox*)GetDlgItem(IDC_WORKADDR))->AddString("杭州");
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
Prop2:四个checkBox,同样也要对每个控件都进行创建关联变量,类型为BOOL
Prop3:一个ComboBox
同样对ComboBox重写虚函数OnInitDialog进行初始化
BOOL CProp3::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: 在此添加额外的初始化
((CComboBox*)GetDlgItem(IDC_SALARY))->AddString("1000 元以下");
((CComboBox*)GetDlgItem(IDC_SALARY))->AddString("1000 - 2000 元");
((CComboBox*)GetDlgItem(IDC_SALARY))->AddString("2000 - 5000 元");
((CComboBox*)GetDlgItem(IDC_SALARY))->AddString("5000 元以上");
((CComboBox*)GetDlgItem(IDC_SALARY))->SetCurSel(0);
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
至此,属性窗口建好了。后面就要利用前面说过的CPropertySheet类,CPropertySheet类对象表示属性表,它由一个或多个CPropertyPage对象构成。前面创建的三个对话框都是CPropertyPage,可以将他们放在一个CPropertySheet中组成一个属性表。
至此,含有三个对话框的属性表准备好了。
创建:
实现:通过类向导,创建刚才创建的菜单的命令响应函数
用属性表单对象(一个CPropertySheet对象)的DoModal之前,先调用SetWizardMode函数,此成员函数用来建立一个作为向导的属性页,它会为每个属性页面(CPropertyPage)生成上一步,下一步,取消按钮。DoModal返回ID_WIZFINISH或IDCANCEL。
void CMFC属性页和向导View::OnProp()
{
// TODO: 在此添加命令处理程序代码
CPropSheet propSheet("个人信息");
propSheet.SetWizardMode(); // DoModal调用该函数将属性页变为向导
if (ID_WIZFINISH == propSheet.DoModal()) // ID_WIZFINISH:用户点击完成,IDCANCEL:取消
{
//这里可以先不用做什么
}
}
为了解决步骤8出现的问题,需要对三个属性对话框进行修改,而且,在点击下一步的时候,应该对选择情况进行判断,并作出相应处理。
需要用到三个虚函数:
OnSetActive() //在该虚函数中调用SetWizardButtons修改向导中按钮
void SetWizardButtons( DWORD dwFlags );
SetWizardButtons参数: dwFlags 参数可以是下列值的组合:
· PSWIZB_BACK Back按钮。
· PSWIZB_NEXT Next按钮。
· PSWIZB_FINISH Finish按钮。
· PSWIZB_DISABLEDFINISH Disabled Finish按钮。
OnWizardNext() //在点击下一步按钮的时候进行判断 返回-1:页面不改变,返回0:页面跳转到下一页
OnWizardFinish() //点击完成按钮处理事件
对Prop1和Prop2添加OnSetActive()、OnWizardNext()虚函数,对Prop3添加OnSetActive()、OnWizardFinish() 虚函数:
CProp1的两个函数代码:
BOOL CProp1::OnSetActive()
{
// TODO: 在此添加专用代码和/或调用基类
((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_NEXT);
return CPropertyPage::OnSetActive();
}
LRESULT CProp1::OnWizardNext()
{
// TODO: 在此添加专用代码和/或调用基类
UpdateData();
if (m_occupation == -1)
{
MessageBox("请选择你的职业!");
return -1;
}
if (m_workAddr == "")
{
MessageBox("请选择你的工作地址!");
return -1;
}
return CPropertyPage::OnWizardNext();
}
CProp2的两个函数代码:
LRESULT CProp2::OnWizardNext()
{
// TODO: 在此添加专用代码和/或调用基类
UpdateData();
if (m_code | m_book | m_game | m_money)
{
return CPropertyPage::OnWizardNext();
}
MessageBox("请选择兴趣爱好!");
return -1;
}
BOOL CProp2::OnSetActive()
{
// TODO: 在此添加专用代码和/或调用基类
((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_NEXT | PSWIZB_BACK);
return CPropertyPage::OnSetActive();
}
CProp3的两个函数代码:
BOOL CProp3::OnSetActive()
{
// TODO: 在此添加专用代码和/或调用基类
((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK | PSWIZB_FINISH);
return CPropertyPage::OnSetActive();
}
BOOL CProp3::OnWizardFinish()
{
// TODO: 在此添加专用代码和/或调用基类
int index = ((CComboBox*)GetDlgItem(IDC_SALARY))->GetCurSel();
((CComboBox*)GetDlgItem(IDC_SALARY))->GetLBText(index, m_salary);
return CPropertyPage::OnWizardFinish();
}
①view类中头文件添加接收向导变量的值
public:
int m_occupation; // 工作
CString m_workAddr; // 工作地址
BOOL m_like[4]; // 兴趣爱好
CString m_salary; // 薪水范围
②构造函数中初始化变量(便于理解 我的项目采用的是中文)
CMFC属性页和向导View::CMFC属性页和向导View()
{
// TODO: 在此处添加构造代码
m_occupation = -1;
m_workAddr = "";
m_salary = "";
memset(m_like,0,sizeof(m_like));
}
③对nDraw函数进行编辑
void CMFC属性页和向导View::OnDraw(CDC* pDC)
{
CMFC属性页和向导Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
CFont font;
font.CreatePointFont(300, "华文行楷");
CFont *pOldFont = pDC->SelectObject(&font);
CString strTmp = "你的职业是:";
switch (m_occupation)
{
case 0:
strTmp += "程序猿";
break;
case 1:
strTmp += "程序媛";
break;
case 2:
strTmp += "BOSS";
break;
default:
break;
}
pDC->TextOut( 0, 0, strTmp);
strTmp = "你的工作地点是:";
strTmp += m_workAddr;
TEXTMETRIC tm;
pDC->GetTextMetrics(&tm);
pDC->TextOut(0, tm.tmHeight, strTmp);
strTmp = "你的兴趣爱好是:";
if (m_like[0])
{
strTmp += " 写代码";
}
if (m_like[1])
{
strTmp += " 看书";
}
if (m_like[2])
{
strTmp += " 打游戏";
}
if(m_like[3])
{
strTmp += " 赚钱";
}
pDC->TextOut(0, tm.tmHeight * 2, strTmp);
strTmp = "你的薪资范围是:";
strTmp += m_salary;
pDC->TextOut(0, tm.tmHeight * 3, strTmp);
pDC->SelectObject(pOldFont);
}
④继续编写“属性”菜单的实现函数
void CMFC属性页和向导View::OnProp()
{
// TODO: 在此添加命令处理程序代码
CPropSheet propSheet("个人信息");
propSheet.SetWizardMode(); // DoModal调用该函数将属性页变为向导
if (ID_WIZFINISH == propSheet.DoModal()) // ID_WIZFINISH:用户点击完成,IDCANCEL:取消
{
m_occupation = propSheet.m_prop1.m_occupation;
m_workAddr = propSheet.m_prop1.m_workAddr;
m_like[0] = propSheet.m_prop2.m_code;
m_like[1] = propSheet.m_prop2.m_book;
m_like[2] = propSheet.m_prop2.m_game;
m_like[3] = propSheet.m_prop2.m_money;
m_salary = propSheet.m_prop3.m_salary;
Invalidate();
}
}
over!