VC中属性表单和向导的创建

本文介绍了如何在VC6中创建属性表单和向导。属性表单通过属性页解决大量信息的展示问题,而向导如AppWizard帮助用户设置信息并生成应用框架。创建属性表单涉及CPropertyPage类和CPropertySheet类的使用,通过添加和修改对话框属性实现。向导模式通过调用SetWizardMode()实现,通过OnWizardNext()和OnWizardFinish()等函数处理用户输入。最后,文章展示了如何在视图类中汇总并显示向导过程中的数据。
摘要由CSDN通过智能技术生成

VC中属性表单和向导的创建本文是在看孙鑫的《VC++深入详解》过程中摘录下来的,作为一份学习笔记。

VC中属性表单和向导的创建首先举例说一下属性表单和向导

    属性表单:在VC6下,打开Tools-Options,弹出的Options对话框就是一个属性表单,其中的每一个选项卡对应一个属性页。属性表单解决了大量信息无法在一个对话框上显示的问题,并提供了对信息的分类和组织管理的功能。

    向导:利用VC6创建一个新工程时使用的AppWizard工具通过一般般引导用户设置一下信息,从而生成相应的应用程序框架,这就是一个向导的实例。

    为了创建属性表单,先要创建属性页。属性页对应的MFC类是CPropertyPage,其继承层次结构为CObject-CCmdTarget-CWnd-CDialog-CPropertyPage。因此一个属性页窗口其实就是一个对话框窗口。为工程添加3个属性页(在Insert Resource窗口的Dialog的IDD_PROPPAGE_**就是的)。打开属性页资源的属性对话框,然后和普通对话框的属性相比较,发现属性很类似,只有几个区别:在Styles下,前者的Sytle是Child,Border是Thin,Symtem menu未选中,后者对应的是Popup和Dialog Frame,选中;在More Styles下,前者的Disabled选中(这样在初始显示时不能使用),后者没有选中。因此,也可以添加一个普通对话框,然后修改其属性使得和属性页的属性一致,就可以把它当属性页使用了。

    为三个属性页添加各自对应的类CProp1、CProp2、CProp3,注意Base Class选择CPropertyPage。

    接下来就是创建属性表单:创建一个CPropertySheet(其继承层次结构为CObject-CCmdTarget-CWnd-CPropertySheet)对象CPropSheet,在此对象中为每一个属性页创建一个对象,并调用CPropertySheet对象的成员函数AddPage添加每一个属性页,然后调用DoModel显示模特属性表单或者调用Create函数创建一个非摸态属性页表。首先在CPropSheet的头文件中添加三个属性页的头文件(#include "Prop1.h"····),然后在头文件中为先前建立的属性页定义一个成员对象(CProp1 m_prop1、CProp2 m_prop2、CProp3 m_prop3),然后就可以在CPropSheet的构造函数中添加属性页对象(注意:CPropSheet有两个构造函数,为了防止你调用不同的方式进行初始化时出现意外,最后在两个构造函数中都调用AddPage函数添加属性页对象AddPage(&m_prop1)、AddPage(&m_prop2)、AddPage(&m_prop2))。

     这里,我采用动态添加菜单项,然后当用户点击这个菜单项时就弹出该属性页表。步骤如下:1.添为菜单项添加一个新的ID:IDM_PROPERTYSHEET并指定一个唯一的值;2.在***View.h中 DECLARE_MESSAGE_MAP()之前添加一个消息响应函数的声明: afx_msg void OnPropertySheet();//手动添加的菜单项响应函数声明;3.在***View.cpp中的消息映射表中添加一行消息映射(END_MESSAGE_MAP()之前)ON_COMMAND(IDM_PROPERTYSHEET,OnPropertySheet)//手动添加消息映射;4.在***View.cpp中添加消息响应函数的实现//手动添加菜单响应函数的实现
void CPropertyPageView::OnPropertySheet()
{
 CPropSheet propsheet(_T("属性表单"));
 propsheet.DoModal();//打开属性表单
}

运行截图:

VC中属性表单和向导的创建

运行后,可能发现汉字显示的是乱码,这是因为插入属性页资源时,它默认的语言是English。因此必须将默认的语言改为中文,同时还有改变字体。方法如下:在ResourceView选项卡上,在相应的属性页上单击鼠标右键,选择Properties,将Language改为Chinese(P.R.C);然后打开属性页资源,在资源上单击鼠标右键,选择Properties,将字体改为"STSong"(也可能是”宋体“),反正是中文的字体就行。再次运行,中文正常显示。解决资源上中文乱码的现象就是这个过程了,得记好了。

 

 

 VC中属性表单和向导的创建接下来,就是向导的创建了:

在propsheet.Domodal()之前加上propsheet.SetWizardMode(),再次运行,它的底部按钮就成了“Back”、“Next”和“Cancel”了,通过“Next”和“Back”我们就可以进入不同的属性页了。这些按钮是属性页表的,属性页是属性页表的子窗口。显然,第一个属性页不应当有"Back",最后一个属性页应该把"Next"换为"Finish"。CPropertySheet类提供了一个用来设置向导对话框上的按钮函数void SetWizardButtons(DWORD dwFlags)(参数有PSWIZB_BACK、PSWIZB_NEXT、PSWIZB_FINISH、PSWIZB_DISABLEDFINISH,分别设置上一步、下一步、完成、和禁用的完成按钮)。当属性页被选中时成为一个活动的页面时,应用程序框架就好调用OnSetActive函数,因此应该在属性页的OnSetActive函数中调用SetWizardButtons函数。OnSetActive是一个虚函数,因此应该针对每个属性页重载该函数,然后再函数体内添加((CPropertySheet*)GetParent())->SetWizardButtons(响应的按钮参数).

 

VC中属性表单和向导的创建处理向导过程中的每一个页面,要求用户适当的操作后才能进入到下一个页面

 

针对第一个属性页为其添加WM_INITDIALOG消息响应函数OnInitDialog,并在函数体内位ID号为IDC_LIST1的ListBox添加字符串

//为CProp1添加了WM_INIDIALOG消息响应函数
BOOL CProp1::OnInitDialog()
{
 CPropertyPage::OnInitDialog();
 
 // TODO: Add extra initialization here
 //想列表框中添加字符串
 ((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
               // EXCEPTION: OCX Property Pages should return FALSE
}

运行后就有了如下的界面

VC中属性表单和向导的创建

为RaidoButton添加一个int型的变量m_job,为ListBox添加一个CString型的变量m_address

接着重载CProp1的虚函数OnWizardNext

LRESULT CProp1::OnWizardNext()
{
 // TODO: Add your specialized code here and/or call the base class
 UpdateData();//从控件上获取信息
 if(!GetCheckedRadioButton(IDC_RADIO1,IDC_RADIO3))//返回被选中的RadioButton或0(未选中)
 {
  AfxMessageBox(_T("请选择你的职业"));
  return -1;
 }

 CString str;
 if(((CListBox*)GetDlgItem(IDC_LIST1))->GetCurSel()==-1)//为选中ListBox中的内容
 {
  AfxMessageBox(_T("请选择工作地点"));
  return -1;
 }
 return CPropertyPage::OnWizardNext();
}

就这样,第一个属性页的就要求用户必须选定相关信息才能进入下一个页面

针对第二个属性页:

VC中属性表单和向导的创建

为4个CheckBox添加对应的BOOL型变量m_check1,m_check2,m_check3,m_check4

接着重载函数OnWizardNext

LRESULT CProp2::OnWizardNext()
{
 // TODO: Add your specialized code here and/or call the base class
 UpdateData();
 if(m_check1||m_check2||m_check3||m_check4)
     return CPropertyPage::OnWizardNext();
 else
 {
  AfxMessageBox(_T("请选择你的爱好"));
  return -1;
 }
}

针对第3个属性页:

重载CProp3的

为其添加WM_INITDIALOG消息响应函数OnInitDialog,并去掉Combo Box的Sort属性

BOOL CProp3::OnInitDialog()
{
 CPropertyPage::OnInitDialog();
 
 // TODO: Add extra initialization here
 ((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))->SetCurSel(0);//设置一个默认的选项
 return TRUE;  // return TRUE unless you set the focus to a control
               // EXCEPTION: OCX Property Pages should return FALSE
}

VC中属性表单和向导的创建

为CProp3添加一个CString类型的m_salary,用于保存薪水的值

接着重载函数OnWizardFinish()

BOOL CProp3::OnWizardFinish()
{
 // TODO: Add your specialized code here and/or call the base class
 int index=((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCurSel();//获取被选的索引值
 ((CComboBox*)GetDlgItem(IDC_COMBO1))->GetLBText(index,m_salary);//读取薪水
 return CPropertyPage::OnWizardFinish();
}

 


VC中属性表单和向导的创建最后是将用户在向导中设置的数据汇总后显示在视类中

在***View类中添加4个成员变量:int m_job;CString m_address;BOOL m_like[4];CString m_salary

在视类的构造函数里初始化数据成员

CPropertyPageView::CPropertyPageView()
{
 // TODO: add construction code here

 m_job=-1;
 m_address=_T("");
 //void *memset(void *dest,int c,size_t count)//将dest指定的内存中前count字节设置为c
 memset(m_like,0,sizeof(m_like));//对数组进行快速初始化
 m_salary=_T("");
}

 

在前面的OnPropertySheet函数里添加一些代码,如下:

//手动添加菜单响应函数的实现
void CPropertyPageView::OnPropertySheet()
{
 CPropSheet propsheet(_T("属性表单"));
 propsheet.SetWizardMode();
 //一般情况下CPropertySheet类的DoModal函数返回IDOK或IDCANCEL
 //若属性表被创建为向导,则返回值就是ID_WIZFINISH或IDCANCEL
 if(propsheet.DoModal()==ID_WIZFINISH)
 {
        m_job=propsheet.m_prop1.m_job;
        m_address=propsheet.m_prop1.m_address;
  m_like[0]=propsheet.m_prop2.m_check1;
  m_like[1]=propsheet.m_prop2.m_check2;
  m_like[2]=propsheet.m_prop2.m_check3;
  m_like[3]=propsheet.m_prop2.m_check4;
  m_salary=propsheet.m_prop3.m_salary;
        //让视图窗口无效,从而引起重绘操作,然后就可以在OnDraw函数输出相关信息
  Invalidate();
 }
}

在OnDraw函数里添加相关代码显示向导过程中获取的数据

void CPropertyPageView::OnDraw(CDC* pDC)
{
 CPropertyPageDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 // TODO: add draw code for native data here
 CFont *pfont=new CFont();
 pfont->CreatePointFont(300,_T("华文行楷"));
 CFont *pOldFont=pDC->SelectObject(pfont);//保存先前的画笔

 CString str(_T("你的职业:"));

 switch(m_job)
 {
 case 0:str+=_T("程序员");
  break;
 case 1:str+=_T("数据库工程师");
  break;
 case 2:str+=_T("系统分析师");
  break;
 default:
  break;
 }
    pDC->TextOut(0,0,str);

 str=_T("你的工作地点:");
 str+=m_address;
 //获取字体的信息
 TEXTMETRIC tm;
 pDC->GetTextMetrics(&tm);
 pDC->TextOut(0,tm.tmHeight,str);

 str=_T("你的兴趣爱好:");
 if(m_like[0]) str+=_T(" 足球");
 if(m_like[1]) str+=_T(" 篮球");
 if(m_like[2]) str+=_T(" 排球");
 if(m_like[3]) str+=_T(" 乒乓球");
 pDC->TextOut(0,tm.tmHeight*2,str);

 str=_T("你的薪资水平:");
 str+=m_salary;
 pDC->TextOut(0,tm.tmHeight*3,str);

 pDC->SelectObject(pOldFont);//恢复先前的画笔

}
最后的运行结果如下图所示:

VC中属性表单和向导的创建


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值