属性页对话框
分类
标签式和向导式
相关类
CPropertyPage-父类是CDialog类,称为属性页或页面对话框。
CPropertySheet-父类是CWnd,称为属性表单。
一个完整的属性页对话框由一个属性表单+多个属性页组成。属性页嵌套在属性表单内。
标签式属性页的创建步骤:
1 插入属性页对话框资源,选中对话框资源ID修改语言为Chinese(P.R.C), 选中资源视图的右边的对话框右键选择属性设置为宋体,9号字体,双击资源,生成相应的类,注意父类选择CPropertyPage类。
2 右击工程,选择添加新的类,父类是CPropertySheet类。
3 在表单类中添加属性页对象。在构造函数中,
CPropertySheet::AddPage
4 创建和显示属性页
CPropertySheet::DoModal()
5 当控件的值发生改变时,将应用按钮设置为可用
CPropertyPage::SetModified(TRUE);
6 消息处理(通过在页面类中添加虚函数的方式实现)
CPropertyPage::OnApply
CPropertyPage::OnOK
CPropertyPage::OnCancel
新建一个MFC当文档应用程序,为菜单添加一个菜单项,在该菜单项的点击处理函数中弹出我们的属性页对话框。
为了演示效果,在视图类的OnDraw函数中创建画笔,然后绘制一个图形,画笔的线宽和颜色由其成员变量m_nWidth和m_color决定,这里正是在属性页对话框中设置线宽和颜色然后作用到上面绘制的图形上。
为视图类添加两个成员变量:
int m_nWitdh;// 线宽
COLORERF m_color; // 颜色
并在视图类的构造函数中初始化
m_nWidth = 1;
m_color = RGB (0, 0, 0);
视图的OnDraw添加绘图代码如下:
void CMFCLabelView::OnDraw(CDC* pDC)
{
CMFCLabelDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CPen pen;
pen.CreatePen (PS_SOLID, m_nWidth, m_color);
CPen *pOldPen = pDC->SelectObject (&pen);
pDC->Ellipse (100, 100, 400, 400);
pDC->SelectObject (pOldPen);
pen.DeleteObject ();
}
添加菜单项
插入对话框资源,注意选择PROPPAGE类型的对话框资源
选中对话框资源,右键更改语言为P.R.C
然后在资源视图右边窗口选中对话框资源右键属性修改字体为宋体9号:
复制一个刚才我们新建的并且调整好语言和字体的对话框
注意:其中一个为线宽设置对话框,给它添加一个编辑框控件用以输入数值
另外一个为颜色设置对话框,给它添加一个按钮,点击按钮弹出颜色对话框
双击他们通过类向导生成相应的类,注意选择父类为CpropertyPage
这里分别命名为:CPage1和CPage2
Ctrl+W为线宽设置对话框的编辑框控件绑定一个int类型的值变量:m_nLineWidth并设置其范围为: 1 –20,并在其构造函数中初始化为1。
在工程上右键选择New Class 注意选择父类为CpropertySheet, 这里类名我设置为:ClabelSheet,然后为该类添加两个成员变量:
CPage1 m_page1;
CPage2 m_page2;
然后在ClabelSheet的两个构造函数中都添加属性页(这样无论调用哪个都可以正确添加):
AddPage (&m_page1);
AddPage (&m_page2);
注意包含:Page1.h 和Page2.h头文件
Ctrl+W为视图类添加菜单的命令消息响应函数,添加如下创建标签式属性页的代码:
注意包含:LabelSheet.h头文件
为了使当用户输入数据时让属性页对话框上的应用按钮变为可用状态,为线宽设置对话库类CPage1的编辑框控件添加EN_CHANGE消息响应函数,当编辑框内容一旦改变将触发该消息,
消息响应函数如下:
void CPage1::OnChangeEditLinewidth()
{
// 设置应用按钮为可用状态
SetModified (TRUE);
}
为了在用户点击应用按钮时把用户的设置反应在视图类的窗口绘图上,我们需要响应应用按钮的消息,然而我们无法直接通过双击应用按钮位它添加消息,正确的做法是通过添加虚函数的方式,此外还有确定, 下一步,等一切属性页对话框上的按钮事件都是虚函数。
那么这里我给CPage1添加一个虚函数OnApply来响应”应用”按钮事件
并添加如下代码来影响视图窗口图形的绘制:
BOOL CPage1::OnApply()
{
// TODO: Add your specialized code here and/or call the base class
// 从控件接收数据到变量
UpdateData (TRUE);
// 获取视图类对象指针
CMFCLabelView *pView = (CMFCLabelView*)(((CFrameWnd*)AfxGetMainWnd ())->GetActiveView ());
// 改变视图类的线宽
pView->m_nWidth = m_nLineWidth;
// 使视图窗口重绘
pView->Invalidate ();
return CPropertyPage::OnApply();
}
这个时候编译会包一些错误发现是一些头文件包含问题
首先在Page1中包含MFCLabelView.h
然后在MFCLabelView中包含MFCLabelDoc.h
再编译就Ok了,设置线宽后点应用按钮在视图窗口中可以看到效果。
回到CPage2类的对话框资源对话框,双击“设置颜色”按钮添加响应事件,编写如下代码:
#include "MFCLabelView.h"
void CPage2::OnBtnSetcolor()
{
// TODO: Add your control notification handler code here
CColorDialog dlg;
if (IDCANCEL == dlg.DoModal ())
return;
CMFCLabelView *pView = (CMFCLabelView*)(((CFrameWnd*)AfxGetMainWnd ())->GetActiveView ());
pView->m_color = dlg.GetColor ();
pView->Invalidate ();
}
向导式属性页的创建步骤:
1 插入属性页对话框资源,选中对话框资源ID修改语言为Chinese(P.R.C), 选中资源视图的右边的对话框右键选择属性设置为宋体,9号字体,双击资源,生成相应的类,注意父类选择CPropertyPage类。
2 右击工程,选择添加新的类,父类是CPropertySheet类。
3 在表单类中添加属性页对象。在构造函数中,
CPropertySheet::AddPage
4 创建和显示前,设置为向导模式
CPropertySheet::SetWizardMode
5 创建和显示
CPropertySheet::DoModal()
6 设置每个页面的向导按钮,在属性页对话框对应的类中添加下面的函数
6.1 在CPropertyPage::OnSetActive()函数中设置
6.2 在页面中得到表单对象
GetParent()
6.3 设置向导按钮
CPropertySheet::SetWizardButtons()
7 消息处理函数,在属性页对话框对应的类中添加下面的虚函数函数
CPropertyPage::OnSetActive()
CPropertyPage::OnCancel()
CPropertyPage::OnWizardNext()
CPropertyPage::OnWizardBack()
CPropertyPage::OnWizardFinish()
这里简单起见直接修改本工程为向导模式:来到标签式属性对话框创建的地方,修改代码:
void CMFCLabelView::OnLabel()
{
// TODO: Add your command handler code here
/*
// 构造标签式(默认)属性页
CLabelSheet sheet ("标签式属性页");
// 显示
sheet.DoModal ();
*/
// 构造向导式属性页
CLabelSheet sheet ("向导式属性页");
// 设置为向导模式
sheet.SetWizardMode ();
// 显示
sheet.DoModal ();
}
#include "LabelSheet.h"
BOOL CPage1::OnSetActive()
{
// TODO: Add your specialized code here and/or call the base class
// 获取父窗口指针(sheet)
CLabelSheet* pSheet = (CLabelSheet*)GetParent ();
// 设置只有"下一步"按钮可用
pSheet->SetWizardButtons (PSWIZB_NEXT);
return CPropertyPage::OnSetActive();
}
同理颜色设置对话框只能有 上一步 和 完成按钮
#include "LabelSheet.h"
BOOL CPage2::OnSetActive()
{
// TODO: Add your specialized code here and/or call the base class
// 获取父窗口指针(sheet)
CLabelSheet* pSheet = (CLabelSheet*)GetParent ();
// 设置:"上一步"和“完成”按钮为可用状态
pSheet->SetWizardButtons (PSWIZB_BACK | PSWIZB_FINISH );
return CPropertyPage::OnSetActive();
}
那么我们想在线宽设置对话框设点击“下一步”按钮时把用户的输入设置到视图的显示,中,需要重写虚函数CPropertyPage::OnWizardNext()
LRESULT CPage1::OnWizardNext()
{
// TODO: Add your specialized code here and/or call the base class
// 从控件接收数据到变量
UpdateData (TRUE);
// 获取视图类对象指针
CMFCLabelView *pView = (CMFCLabelView*)(((CFrameWnd*)AfxGetMainWnd ())->GetActiveView ());
// 改变视图类的线宽
pView->m_nWidth = m_nLineWidth;
// 使视图窗口重绘
pView->Invalidate ();
return CPropertyPage::OnWizardNext();
}