资源描述
,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,#,6.1,属性单和属性页相关类,6.2,创建属性单和属性页程序,6.3,创建向导属性单应用程序,6.1 属性单和属性页相关类,1,6.1,属性单和属性页相关类,MFC,库提供了两个支持属性单的重要类:,CPropertySheet,类和,CPropertyPage,类,分别对属性单和属性页进行了封装,.,CPropertySheet,类是,CWnd,类的一个派生类,作为属性页对话框的窗口框架出现,主要实现管理各个属性页面的作用,一个属性单可以包含一个,CPropertySheet,类(或者其派生类)的对象和多个,CPropertyPage,类(或者其派生类)的对象。,6.1 属性单和属性页相关类MFC库提供了两个支持属性单的重,2,1,CPropertySheet,类,CPropertySheet,类的对象表示属性表,通常由一个或多个属性页对象组成。,PropertySheet,类不是,CDialog,类的派生类,但是在使用该类时却和,CDialog,类非常相似:首先运行,CPropertySheet,类的构造函数,然后调用,DoModal,()函数实现一个模式属性单对话框,或者调用,Creat,()函数实现一个非模式属性单对话框。,1CPropertySheet类CPropertyShee,3,(,1,),CPropertySheet,方法,其原型为:,CPropertySheet( );,CPropertySheet ( UINT nIDCaption,CWnd *pParentWnd=NULL,UINT iSelectPage=0);,CPropertySheet (LPCTSTR pszCaption,CWnd *pParentWnd=NULL,UINT iSelectPage=0);,(1)CPropertySheet方法,4,(2)Construct,方法,其原型为:,void Construct(UINT nIDCaption,CWnd *pParentWnd=NULL,UINT iSelectPage=0);,void Construct(LPCTSTR pszCaption,CWnd *pParentWnd=NULL,UINT iSelectPage=0);,(2)Construct方法,5,(,3,),GetActivePage,方法,其原型为:,CPropertyPage* GetActivePage( ) const;,(3)GetActivePage方法,6,(,4,),SetActivePage,方法,其原型为:,BOOL SetActivePage( int nPage );,BOOL SetActivePage( CPropertyPage* pPage );,(4)SetActivePage方法,7,(,5,),DoModal,方法,其原型为:,virtual int DoModal( );,(5)DoModal方法,8,(,6,),Create,方法,其原型为:,BOOL Create( CWnd* pParentWnd = NULL, DWORD dwStyle = (DWORD),1, DWORD dwExStyle = 0 );,(6)Create方法,9,(,7,),AddPage,方法,其原型为:,void AddPage( CPropertyPage *pPage );,(7)AddPage方法,10,(,8,),RemovePage,方法,其原型为:,void RemovePage( CPropertyPage *pPage );,void RemovePage( int nPage );,(8)RemovePage方法,11,(,9,),EndDialog,方法,其原型为:,void EndDialog( int nEndID );,(9)EndDialog方法,12,2,CPropertyPage,类,该类从对话框类派生,它的对象表示单个的属性页。使用方法如同使用标准的对话框一样,进行数据交换时,也是通过变量和属性页控件进行数据交换来完成的。,该类实现了对属性页的封装,同时还提供一些非常有用的成员函数和成员变量,通过这些成员,可以很方便的操作和定制属性页的各个特性。,2CPropertyPage类该类从对话框类派生,它的对象,13,(,1,),CPropertyPage,方法,其原型为:,CPropertyPage( );,CPropertyPage( UINT nIDTemplate, UINT nIDCaption = 0 );,CPropertyPage( LPCTSTR lpszTemplateName, UINT nIDCaption = 0 );,(1)CPropertyPage方法,14,(,2,),Construct,方法,其原型为:,void Construct( UINT nIDTemplate, UINT nIDCaption = 0 );,void Construct( LPCTSTR lpszTemplateName, UINT nIDCaption = 0 );,(2)Construct方法,15,(,3,),OnApply,方法,其原型为:,virtual BOOL OnApply( ),ASSERT_VALID(this);,OnOK();,return TRUE;,(3)OnApply方法,16,(,4,),OnOK,方法,其原型为:,virtual void OnOK( );,ASSERT_VALID(this);,(4)OnOK方法,17,(,5,),OnSetActive,方法,其原型为:,virtual BOOL OnSetActive( );,(5)OnSetActive方法,18,(,6,),OnKillActive,方法,其原型为:,virtual BOOL OnKillActive( );,(6)OnKillActive方法,19,6.2,创建属性单和属性页程序,属性对话框能同时提供多个选项页,而每页都可以由资源编辑器以编辑对话框的方式进行编辑,这样给界面开发带来了方便。,创建属性单和属性页程序的步骤是:,(,1,)利用资源编辑器创建属性页资源;,(,2,)运行,CPropertySheet,类的构造函数;,(,3,)调用,DoModal,()函数实现一个模式属性页对话框,或者调用,Creat,()函数实现一个非模式属性页对话框。,6.2 创建属性单和属性页程序 属性对话框能同时提供多个选项,20,例,6-1,:创建一个单文档应用程序实现画圆功能。在主菜单上添加菜单项,“,设置,”,,当单击此菜单项时弹出设置对话框,共有三个页面,第一页设置圆的半径;第二页设置圆的边框颜色;第三页设置圆的填充颜色。,注意:要求在初次运行程序时显示一个黑色边框,填充颜色为白色,半径为,50,的圆。,例6-1:创建一个单文档应用程序实现画圆功能。在主菜单上添加,21,6.2.1,创建属性页资源,创建属性页资源有两种方法,1.,在插入资源对话框中选择属性页来实现如图,6-2,插入资源对话框 :,6.2.1 创建属性页资源创建属性页资源有两种方法,22,2.,选择插入一个普通对话框,然后修改其属性使其成为一个属性页。,这两种对话框的主要区别有以下几点:,(,1,)在,“,样式,”,上,普通对话框的样式为,“,弹出,”,,边框为,“,对话框架,”,,而属性页的样式为,“,子窗口,”,,边框为,“,细小,”,(,2,)在,“,更多样式,”,选项卡中,普通对话框的,“,已禁止,”,没有选中,这个选项主要控制对话框初始状态下是否可用。根据这两个不同点进行修改,就可以把一个普通对话框变为一个属性页对话框。,2.选择插入一个普通对话框,然后修改其属性使其成为一个属性页,23,针对例,6-1,,要完成题目要求的功能,需要首先做如下工作:,(,1,)利用,MFC App Wizard,向导生成单文档(,SDI,)应用程序,PropertySheetTest,。在项目工作区的资源页面中选择,Menu,并展开,再双击,IDR_MAINFRAME,项弹出菜单资源编辑器,添加,“,测试,”,主菜单,该菜单对应的,ID,标识为,ID_DIALOG_TEST,。,针对例6-1,要完成题目要求的功能,需要首先做如下工作,24,(2),打开插入资源对话框,按照图,6-2,所示选择,“,IDD_PROPPAGE_MEDIUM,”,选项,然后单击,“,新建,”,完成第一个属性页对话框的插入,按照相同的方法添加第二个属性页的添加。,(2)打开插入资源对话框,按照图6-2所示选择“IDD_PR,25,(,3,)按照要求添加各个页面的主要控件,控件属性如表,:,(3)按照要求添加各个页面的主要控件,控件属性如表 :,26,对话框,控件类型,控件,ID,设置的非默认属性,设置,半径,静态文本,IDC_STATIC,Caption,为,“,请输入半径:,”,编辑框,IDC_INPUT_RADIUS,边框,颜色,(,填充,颜色,),组框,IDC_BORDER_COLOR,Caption,为,“,边框颜色:,”,静态文本,IDC_STATIC,Caption,为,“,红色(,0-255,),”,静态文本,IDC_STATIC,Caption,为,“,绿色(,0-255,),”,静态文本,IDC_STATIC,Caption,为,“,蓝色(,0-255,),”,编辑框,IDC_RED,编辑框,IDC_GREEN,编辑框,IDC_BLUE,对话框 控件类型 控件ID 设置的非默认属性 设置静态文本,27,“,设置边框颜色,”,和,“,设置填充颜色,”,对话框中的控件基本一致,三个对话框的,ID,分别为:,IDD_DLGRADIUS,、,IDD_DLGBORDER,、,IDD_DLGFILL,。,设置,3,个对话框的标题分别为,“,设置半径,”,、,“,设置边框颜色,”,和,“,设置填充颜色,”,,这样就完成了对话框资源的创建,使用,“,Ctrl+T,”,查看运行状态,“设置边框颜色”和“设置填充颜色”对话框中的控件基本一致,三,28,6.2.2,创建,CPropertyPage,类,建立好属性页资源之后,就可以根据这个对话框资源生成一个新类,可以利用,MFC,的,Class Wizard,来实现,.,6.2.2 创建CPropertyPage类建立好属性页资,29,通过,“,查看,”,“,建立类向导,”,菜单命令,也可以使用快捷键,“,Ctrl+W,”,来打开类向导,但由于添加的属性页对话框资源并没有相应的类,因此会弹出添加类对话框,如图所示。,通过“查看” “建立类向导”菜单命令,也可以使用快捷,30,选择,OK,后设置对话框类以及该类的基类,如图所示。,选择OK后设置对话框类以及该类的基类,如图所示。,31,为了进行数据交换,还需要为每个对话框中需要传递数据的控件添加对话框成员变量,可以通过,“,Ctrl+W,”,打开对应的类向导,选择,“,Member Variables,”,添加成员变量,如表所示。,为了进行数据交换,还需要为每个对话框中需要传递数据的控件添加,32,对话框,控件,ID,成员变量,变量类型,设置半径,IDC_INPUT_RADIUS,m_nRadius,UINT,边框颜色,(,填充颜色,),IDC_RED,m_nRed,UINT,IDC_GREEN,m_nGreen,UINT,IDC_BLUE,m_nBlue,UINT,对话框 控件ID 成员变量 变量类型 设置半径 IDC_IN,33,6.2.3,创建,CPropertySheet,类,单击,“,插入,|,类,”,菜单选项来添加新的类,也可以使用快捷键,“,Ctrl+W,”,打开类向导来添加,两者都可以添加新的类,但最主要的不同点在于:,(,1,)前者建立的类可以以,“,CObject,”,为基类,而后者不可以;,(,2,)如果编程需要添加一个不以任何类为基类的新类时,使用前者实现非常方便。使用两者均可以实现添加,CPropertySheet,类,可以选择其中的任意一种来完成此工作,使用前者添加如图所示。,6.2.3创建CPropertySheet类单击“插入|,34,VisualC程序设计教程属性单CPropertySheet课件,35,为了能在属性单中显示我们已经建立好的三个属性页对话框,就需要使用属性单的成员函数将属性页添加到属性单中,为了实现这一目的,1.,在,CProSheet,类中引入,3,个属性页类的头文件:,#include DlgRadius.h,#include DlgBorder.h,#include DlgFill.h,为了能在属性单中显示我们已经建立好的三个属性页对话框,就需要,36,2.,在该类声明中加入,3,个成员变量:,public:,CDlgRadius m_pageRadius;,CDlgBorder m_pageBorder;,CDlgFill m_pageFill;,2.在该类声明中加入3个成员变量:,37,在属性单,CProSheet,的构造函数中将属性页添加上去,可以看到该类有两个构造函数,分别添加代码如下:,CPropSheet:CPropSheet(UINT nIDCaption, CWnd*pParentWnd, UINT iSelectPage),:CPropertySheet(nIDCaption, pParentWnd, iSelectPage),this-AddPage(,this-AddPage(,this-AddPage(,在属性单CProSheet的构造函数中将属性页添加上去,可以,38,CPropSheet:CPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage),:CPropertySheet(pszCaption, pParentWnd, iSelectPage),this-AddPage(,this-AddPage(,this-AddPage(,VisualC程序设计教程属性单CPropertySheet课件,39,6.2.4,显示属性单,显示属性单可以调用,DoModal,()函数实现一个模式属性单对话框,也可以调用,Create,()函数实现一个非模式属性单对话框,仍然结合例,6-1,,使用模式对话框方式实现。,6.2.4 显示属性单显示属性单可以调用DoModal(),40,(,1,)添加对菜单项,“,测试,”,的菜单命令响应函数,打开,Class Wizard,类向导对话框,在,Class name,中选择,“,CPropertySheetTestView,”,类,在,Object IDs,中选择,ID_DIALOG_TEST,,添加对,Command,消息的响应,将函数,OnDialogTest,()映射到视图类中。,(1)添加对菜单项“测试”的菜单命令响应函数,打开Class,41,(,2,)为了保存在属性页对话框中选择的半径和颜色值,为视图类头文件中添加成员变量。,private:,UINT m_nRadiusView;,COLORREF m_borderColor;,COLORREF m_fillColor;,在视图类中添加对属性单类的引用,#include PropSheet.h,(2)为了保存在属性页对话框中选择的半径和颜色值,为视图类头,42,(,3,)使用,CPropertySheet,类的构造函数定义一个类对象,然后调用,DoModal,()函数显示模式模式单,并将属性页中输入值传递给视图类的成员变量,这段代码添加在,OnDialogTest,()函数中。,void CPropertySheetTestView:OnDialogTest( ),/ TODO: Add your command handler code here,/,标题为,“,属性单窗口,”,,父窗口是视图类窗口,属性单第一个页面是设置半径属性页,CPropSheet propSheet(,属性单窗口,this,0);,if (propSheet.DoModal()=IDOK)/,模式属性单,m_nRadiusView=propSheet.m_pageRadius.m_nRadius;,(3)使用CPropertySheet类的构造函数定义一个类,43,m_borderColor=RGB(propSheet.m_pageBorder.m_nRed,propSheet.m_pageBorder.m_nGreen,propSheet.m_pageBorder.m_nBlue);,m_fillColor=RGB(propSheet.m_pageFill.m_nRed,propSheet.m_pageFill.m_nGreen,propSheet.m_pageFill.m_nBlue);,Invalidate();/,刷新视图类窗口,m_borderColor=RGB(propSheet.m_,44,(,4,)为了能完成初次运行时的画圆要求,还需要在视图类中对半径、边框颜色和填充颜色变量进行初始化,同时要实现按照设置的半径和颜色绘制圆形,还需要在,OnDraw,()函数中添加画圆的程序代码。,CPropertySheetTestView:CPropertySheetTestView(),/ TODO: add construction code here,m_nRadiusView=50;/,初始圆半径为,50,m_borderColor=RGB(0,0,0);/,初始圆边框颜色为黑色,m_fillColor=RGB(255,255,255);/,初始圆填充颜色为白色,(4)为了能完成初次运行时的画圆要求,还需要在视图类中对半径,45,void CPropertySheetTestView:OnDraw(CDC* pDC),CPropertySheetTestDoc* pDoc = GetDocument();,ASSERT_VALID(pDoc);,/ TODO: add draw code for native data here,CPen penNew,*pPenOld;,penNew.CreatePen(PS_SOLID,1,m_borderColor);/,创建新画笔,pPenOld=pDC-SelectObject(,CBrush brushNew,*pBrushOld;,void CPropertySheetTestView:O,46,brushNew.CreateSolidBrush(m_fillColor);,pBrushOld=pDC-SelectObject(,pDC-Ellipse(0,0,2*m_nRadiusView,2*m_nRadiusView);,pDC-SelectObject(pPenOld);,pDC-SelectObject(pBrushOld);,penNew.DeleteObject();,brushNew.DeleteObject();,brushNew.CreateSolidBrush(m_fi,47,程序运行,效果如图,所示。,VisualC程序设计教程属性单CPropertySheet课件,48,6.3,创建向导属性单应用程序,向导是属性单的一种,与普通属性单和属性页应用程序不同的是,多个属性页对话框并不是并列显示,而是有出现的先后顺序,通常有,“,上一步,”,、,“,下一步,”,、,“,取消,”,和,“,完成,”,等按钮指示用户完成设置的过程。,6.3 创建向导属性单应用程序向导是属性单的一种,与普通属,49,使用,MFC App Wizard,创建应用程序的对话框就是一个向导的例子,每设置完一个属性页,单击,“,下一步,”,即可进行后边的设置,直到单击,“,完成,”,按钮结束设置过程。,要实现向导属性单对话框,有几个重要的函数需要调用,这些函数的作用及功能说明如下:,使用MFC App Wizard创建应用程序的对话框就是一个,50,(,1,),SetWizardMode,方法,其原型为:,void SetWizardMode( );,(,2,),SetWizardButtons,方法,其原型为:,void SetWizardButtons( DWORD dwFlags );,(,3,),SetFinishText,方法,其原型为:,void SetFinishText( LPCTSTR lpszText );,(1)SetWizardMode方法,51,现在对示例,6-1,进行修改,当单击,“,测试,”,菜单命令时,弹出向导属性单对话框,设置完成后,在视图类窗口中画出圆形,其它要求不变。,编程实现步骤 :,(,1,)按照示例,6-1,的实现方法,生成单文档应用程序,添加,“,测试,”,菜单;添加三个属性页对话框资源和相关控件,生成对应的类后添加和控件相关联的成员变量。,现在对示例6-1进行修改,当单击“测试”菜单命令时,弹出向导,52,(,2,)新建属性单类,CWizardSheet,,基类为,CPropertySheet,,按照,6.2.3,节中的内容在该类的头文件中加入,3,个属性页的包含文件,并在类的声明文件中加入属性页成员,最后,还要在构造函数中使用,AddPage,()函数添加,3,个属性页。,(,3,)为应用程序视图类添加,3,个变量,m_nRadiusView,、,m_borderCorlor,和,m_fillColor,并按照题目要求进行初始化工作。,(2)新建属性单类CWizardSheet,基类为CProp,53,(,4,)当属性页被激活时,调用,CPropertyPage,类的,OnSetActive,函数,因此可以在该函数中添加每个属性页的向导按钮。该函数是一个虚函数,所以可以对其重载,添加方法是在要重载虚函数的类上右键单击,弹出的菜单中选择,“,Add Virtual Function,”,命令,弹出如图所示的对话框,选择,OnSetActive,函数后单击,“,Add and Edit,”,按钮即可。,(4)当属性页被激活时,调用CPropertyPage类的O,54,VisualC程序设计教程属性单CPropertySheet课件,55,对,“,设置半径,”,属性页为首页,所以该对话框,“,下一步,”,按钮和取消按钮有效,,“,上一步,”,按钮不可用,代码如下:,BOOL CDlgRadius:OnSetActive(),/ TODO: Add your specialized code here and/or call the base class,CPropertySheet *pParent=(CPropertySheet*)GetParent();,ASSERT(pParent-IsKindOf(RUNTIME_CLASS(CPropertySheet);,pParent-SetWizardButtons(PSWIZB_NEXT);,return CPropertyPage:OnSetActive();,对“设置半径”属性页为首页,所以该对话框 “下一步”按钮和取,56,该对话框运行结果如图所示。,该对话框运行结果如图所示。,57,设置边框颜色对话框为第二页,该页,“,上一步,”,和,“,下一步,”,按钮均可用,代码如下:,BOOL CDlgBorder:OnSetActive(),/ TODO: Add your specialized code here and/or call the base class,CPropertySheet *pParent=(CPropertySheet*)GetParent();,ASSERT(pParent-IsKindOf(RUNTIME_CLASS(CPropertySheet);,pParent-SetWizardButtons(PSWIZB_BACK|PSWIZB_NEXT);,return CPropertyPage:OnSetActive();,设置边框颜色对话框为第二页,该页 “上一步”和“下一步”按钮,58,该对话框运行结果如图所示。,该对话框运行结果如图所示。,59,设置填充颜色对话框为最后一页,该页,“,下一步,”,和,“,完成,”,按钮可用,代码如下:,BOOL CDlgFill:OnSetActive(),/ TODO: Add your specialized code here and/or call the base class,CPropertySheet *pParent=(CPropertySheet*)GetParent();,ASSERT(pParent-IsKindOf(RUNTIME_CLASS(CPropertySheet);,pParent-SetWizardButtons(PSWIZB_BACK|PSWIZB_FINISH);,return CPropertyPage:OnSetActive();,设置填充颜色对话框为最后一页,该页“下一步”和“完成”按钮可,60,该对话框运行结果如图所示。,该对话框运行结果如图所示。,61,(,5,)在视图类头文件中引用,CWizardSheet,类的头文件。,#include WizardSheet.h,(5)在视图类头文件中引用CWizardSheet类的头文件,62,(,6,)为了显示向导属性单对话框,还要对,“,测试,”,菜单项添加菜单命令响应函数,并添加如下代码:,void CPropertySheetTestView:OnDialogTest(),/ TODO: Add your command handler code here,CWizardSheet wizardSheet(,向导对话框示例,this,0);,wizardSheet.SetWizardMode();/,设置向导对话框模式,int nResult= wizardSheet.DoModal();/,模式显示向导对话框,得到返回值,if (nResult=ID_WIZFINISH)/,如果在最后一个属性页单击,“,完成,”,(6)为了显示向导属性单对话框,还要对“测试”菜单项添加菜单,63,/,获取设置半径对话框指针,CDlgRadius *pageRadius=(CDlgRadius*) wizardSheet.GetPage(0);,m_nRadiusView=pageRadius-m_nRadius;/,得到设置的半径值,CDlgBorder *pageBorder=(CDlgBorder*) wizardSheet.GetPage(1);,m_borderColor=RGB(pageBorder-m_nRed,pageBorder-m_nGreen,pageBorder-m_nBlue);,int zz=propSheet.GetPageCount();,64,CDlgFill *pageFill=(CDlgFill*) wizardSheet.GetPage(2);,m_fillColor=RGB(pageFill-m_nRed,pageFill-m_nGreen,pageFill-m_nBlue);,Invalidate();/,刷新窗口,else,AfxMessageBox(,取消设置,);/,如果单击取消,弹出消息提示框,CDlgFill *pageFill=(CDlgFill*,65,(,7,)为了在视图窗口中画出圆形,还需要在,CPropertySheetTestView,类,OnDraw,()函数中添加如下代码:,void CPropertySheetTestView:OnDraw(CDC* pDC),CPropertySheetTestDoc* pDoc = GetDocument();,ASSERT_VALID(pDoc);,/ TODO: add draw code for native data here,CPen penNew,*pPenOld;,penNew.CreatePen(PS_SOLID,1,m_borderColor);/,创建新画笔,(7)为了在视图窗口中画出圆形,还需要在CPropertyS,66,pPenOld=pDC-SelectObject(,CBrush brushNew,*pBrushOld;,brushNew.CreateSolidBrush(m_fillColor);/,创建新画刷,pBrushOld=pDC-SelectObject(,pDC-Ellipse(0,0,2*m_nRadiusView,2*m_nRadiusView);/,根据给定半径绘制圆形,pDC-SelectObject(pPenOld);,pDC-SelectObject(pBrushOld);,penNew.DeleteObject();,brushNew.DeleteObject();,pPenOld=pDC-SelectObject(&pen,67,(,8,)如果此时运行程序进行向导设置,会发现半径和边框颜色会按照设置生效,填充颜色却始终无法起作用。这里主要是因为当单击最后一页,“,设置填充颜色,”,中的完成按钮时,前面两页的数据交换已经完成,但最后一页尚未完成。要解决这一问题,必须重载最后一个属性页的,OnWizardFinish,()函数,以便完成最后页的数据交换工作,从而将用户的设置更新到应用程序中,(8)如果此时运行程序进行向导设置,会发现半径和边框颜色会按,68,代码如下:,BOOL CDlgFill:OnWizardFinish(),/ TODO: Add your specialized code here and/or call the base class,UpdateData(TRUE);/,数据交换,将控件中颜色数据传递给对话框成员变量,return CPropertyPage:OnWizardFinish();,代码如下:,69,整个程序运行结果如图所示。,整个程序运行结果如图所示。,70,在向导对话框设置的任何一个环节如果单击,“,取消,”,按钮,就会弹出消息提示框,说明取消了所做的设置,该对话框如图所示。,在向导对话框设置的任何一个环节如果单击“取消”按钮,就会弹出,71,本章结束,本章结束,72,
展开阅读全文