第8章-对话框(二)学习(下)

一、属性表单和向导的创建

一个属性表单由一个或多个属性页组成。

采用自下而上的方法创建属性表单,所以首先创建属性页

1,创建属性页

在资源视图Dialog中右击【插入资源】,点开Dialog前+号,找到IDD_PROPPAGE_LARGE,点击【新建】,生成一个属性页,修改ID,和Caption.

增加单选按钮(Radio Button),组合框(Group Box)  .....

为属性页创建新的类,以生成对象。


2,创建属性表单

(1)构造新类:为了创建一个属性表单,首先需创建一个继承于CPropertySheet 的类,在类中增加(继承于CPropertyPage属性页类)的对象的成员变量,接下来为在此类构造函数中,调用AddPage()函数添加所有的属性页。

(2)创建新类的对象:在书中,在菜单栏增加一个一个新的菜单项,并且取消新增菜单的属性的【Pop-up】,把【ID】改为IDM_PROPERTYSHEET,然后利用类向导增加新增菜单的命令响应函数,在此函数中首先构造一个新类的属性表单的类对象,然后利用对象调用成员函数DoModal(),创建一个模态的属性表单。如下:

void CPropView::OnPropertysheet()
{
// TODO: 在此添加命令处理程序代码
CPropSheet propSheet(_T("属性表单"));
propSheet.DoModal();

}

到此属性表单就创建完毕了。


3,向导的创建

(1)创建一个向导类型的对话框,应该遵循创建一个标准的属性表单步骤来实现,但在调用属性表单对象的DoModal()之前应该调用propSheet.SetWizardMode();

void CPropView::OnPropertysheet()
{
// TODO: 在此添加命令处理程序代码
CPropSheet propSheet(_T("属性表单"));
propSheet.SetWizardMode();
propSheet.DoModal();

}

(2)由此创建的向导是在第一页有【上一步】按钮,最后一页有【下一步】按钮,这是不应该的,因此要改进向导。调用属性表单类的SetWizardButtons()成员函数,可以修改按钮。但是何时调用、由谁来调用这个函数是个问题。在书中讲到,当属性页被选中,从而成为活动窗口时,应用程序框架就会调用OnSetActive这个函数,并且这个函数是个虚函数,因此可以在属性页子类中重写这个函数,然后根据需要设置该属性页的按钮。具体实现是这样的,利用类向导,在属性页子类中,选中虚函数这栏,找到OnSetActive双击即可完成此函数的重写并定位到函数的定义处。注意:首先获取父窗口的指针(即属性表单),并将其强制转换成(CPropertySheet*)指针。

BOOL CProp1::OnSetActive()
{
// TODO: 在此添加专用代码和/或调用基类
CPropertySheet* psheet = (CPropertySheet*) GetParent();   
    psheet->SetWizardButtons(PSWIZB_NEXT);

return CPropertyPage::OnSetActive();
}

(3)处理界面

(1)把属性页的控件与其他变量相关联。对于单选按钮可以关联int类型,对于一组单选按钮,在第一个按钮的属性选中【Group】,他们变为一组单选按钮了,直到遇到下一个(按照Tab顺序)具有【Group】属性的单选按钮。索引从0开始,没有选中任何一个单选按钮时:索引为-1。

(2)为属性页子类添加一个OnWizardNext()虚函数的处理。

不能忘记调用UpdateData(1);函数:从控件得到成员变量的值。UpdateData(0):用成员变量的事初始化控件。

LRESULT CProp1::OnWizardNext()

{

// TODO: 在此添加专用代码和/或调用基类

UpdateData();

if(m_occupation==-1)

{

MessageBox(_T("请选择你的职业"));

return -1;

}

if(m_workAddr=="")

{

MessageBox(_T("请选择你的工作地点"));

return -1;

}

return CPropertyPage::OnWizardNext();

}

(3)为列表框增加地点。哪里增加?怎么增加?

在属性子类中,添加WM_INITDIALOG消息响应函数,在此函数中完成列表框文本的增加。

BOOL CProp1::OnInitDialog()

{

CPropertyPage::OnInitDialog();

// TODO:  在此添加额外的初始化

((CListBox*)GetDlgItem(IDC_LIST1))->AddString(_T("北京"));

((CListBox*)GetDlgItem(IDC_LIST1))->AddString(_T("上海"));

((CListBox*)GetDlgItem(IDC_LIST1))->AddString(_T("广东"));


return TRUE;  // return TRUE unless you set the focus to a control

// 异常: OCX 属性页应返回 FALSE

}

(4)为列表框(CListBox)关联成员变量,只能关联CString类型。

(5)为复选框(CCheckBox)关联成员变量,用布尔(BOOL)型。

(6)为组合框(CComboBox)关联成员变量,使用CString类型。

在属性子类中,添加WM_INITDIALOG消息响应函数,在此函数中完成列表框文本的增加。

BOOL CProp3::OnInitDialog()
{
CPropertyPage::OnInitDialog();

// TODO:  在此添加额外的初始化
((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString(_T("1000元以下"));
((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString(_T("1000-2000元"));
((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString(_T("2000-3000元"));
((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString(_T("3000元以上"));

((CComboBox*)GetDlgItem(IDC_COMBO1))->SetCurSel(0);            //默认选项
return TRUE;  // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}

在单击【完成】按钮前完成对选择保存,同样增加虚函数的重载。

BOOL CProp3::OnWizardFinish()
{
// TODO: 在此添加专用代码和/或调用基类
int index;
index=((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCurSel();
((CComboBox*)GetDlgItem(IDC_COMBO1))->GetLBText(index,m_strsalary);
return CPropertyPage::OnWizardFinish();
}


4,接收用户在向导做的选择

1,在视类中增加4个成员变量,在构造函数中初始化。

CPropView::CPropView()
{
// TODO: 在此处添加构造代码
m_iOccupation=-1;
m_strWorkAddr="";
memset(m_bLike,0,sizeof(m_bLike));
m_strSalary="";


}

2,保存在向导中选择的变量。怎么保存,何时保存。

void CPropView::OnPropertysheet()
{
// TODO: 在此添加命令处理程序代码
CPropSheet propSheet(_T("属性表单"));
propSheet.SetWizardMode();
if(ID_WIZFINISH==propSheet.DoModal())
{
m_iOccupation=propSheet.m_prop1.m_occupation;
m_strWorkAddr=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_valleyball;
m_bLike[3]=propSheet.m_prop2.m_swim;
m_strSalary=propSheet.m_prop3.m_strsalary;
Invalidate(); //让视类无效,从而引起重绘操作
}

}

3,在视类的OnDraw中完成对选择输出

void CPropView::OnDraw(CDC* /*pDC*/)
{
CPropDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;

// TODO: 在此处为本机数据添加绘制代码
CClientDC dc(this);
CFont font;
CFont* preFont;
font.CreatePointFont(300,_T("华文行楷"));

preFont=dc.SelectObject(&font);
CString str=_T("你的职业是:");
switch(m_iOccupation)
{
case 0:
str+="程序员";
break;
case 1:
str+="系统工程师";
break;
case 2:
str+="项目经理";
break;

default:
break;


}
dc.TextOutW(0,0,str);


str="你的工作地点:";
str+=m_strWorkAddr;
TEXTMETRIC tm;
dc.GetTextMetrics(&tm);

dc.TextOutW(0,tm.tmHeight,str);

str="你的兴趣爱好是:";
if(m_bLike[0])
{
str+="足球 ";
}
if(m_bLike[1])
{
str+="篮球 ";
}
if(m_bLike[2])
{
str+="排球 ";
}
if(m_bLike[3])
{
str+="游泳";
}
dc.TextOutW(0,tm.tmHeight*2,str);


str="你的薪资水平是:";
str+=m_strSalary;
dc.TextOutW(0,tm.tmHeight*3,str);


dc.SelectObject(&preFont);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值