MFC(十三)多个对话框

设置向导模式

1.打开类视图,右键项目--->类向导-->添加Cpropsheet类,命名为mypropsheet

CPropertySheet 是 MFC 的一个类,用于创建包含多个属性页的对话框。它可以使用内置的向导模式,向用户显示“下一步”和“上一步”按钮

2.在Cmypropsheet.h中,声明三个属性类的对象

public:
	PROP01 m_prop01;
	PROP02 m_prop02;
	PROP03 m_prop03;

 3.在构造函数里,把三个对象加进去

Cmypropsheet::Cmypropsheet(UINT nIDCaption, 
    CWnd* pParentWnd, UINT iSelectPage)
	:CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
{
	AddPage(&m_prop01);
	AddPage(&m_prop02);
	AddPage(&m_prop03);
}

4.在第二个构造函数里,也加进去

Cmypropsheet::Cmypropsheet(LPCTSTR pszCaption, 
    CWnd* pParentWnd, UINT iSelectPage)
	:CPropertySheet(pszCaption, pParentWnd, iSelectPage)
{
	AddPage(&m_prop01);
	AddPage(&m_prop02);
	AddPage(&m_prop03);
}

5.在对话框的添加按钮中,加入代码

void CrunningbuttonDlg::OnBnClickedButtonQuery()
{
	Cmypropsheet dlg(__T("职业调查1111 "),this);
	dlg.SetWizardMode();
	dlg.DoModal();
}

第一句是通过mypropsheet构造函数创建了对象,第二个的作用是 设置为向导模式,即有了下一步,帮助,取消等按钮,第三句是创建了一个模态对话框

6.生成后,发现报错了

MFC(十三)多个对话框_第1张图片

 7.我们点击重试,看一下输出窗口,发现输出窗口提示了源码269行有错误,我们打开相应源码,定位到269行

ASSERT(::GetWindowLong(hWndCtrl, GWL_STYLE) & WS_GROUP);

这句的意思是没有设置分组,我们将按钮的组属性进行修改,将false改成true,并将m_lang修改为整型变量而不是数组,至于为什么,我也不清楚

重写帮助、下一步等按钮

1.在在PROP01.cpp中添加重写OnWizardNext()函数

BOOL PROP01::OnSetActive()
{
	((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_NEXT);
	((CPropertySheet*)GetParent())->GetDlgItem(IDHELP)
		->ShowWindow(SW_HIDE);
	return CPropertyPage::OnSetActive();
}

 。OnSetActive() 函数通常被视为初始化属性页的最后一个处理步骤,因此可以在这个函数中完成大部分的初始化和设置操作,例如更新属性页中的数据、设置控件的默认状态等等。

 OnSetActive()CPropertyPage 类的消息处理函数之一,用于处理激活属性页时发出的 PSN_SETACTIVE 通知消息

GetParent() 是一个 MFC 函数,是用于获取当前窗口的父窗口指针的,该函数的返回值是一个 CWnd* 类型的指针,指向当前窗口的父窗口。这句代码的意思是设置一个向前按钮,当前窗口的父类窗口就是指这个属性页,可是这个属性页就是这个当前的窗口,为什么还是父类呢,因为属性页才是当前窗口,而它的父类窗口就是它的对话框窗口,它们两个显示上是同一个窗口,属性页(Property Page)和对话框(Dialog)在视觉上表现为同一个窗口。这是因为属性页实际上是基于对话框窗口来实现的,也就是说属性页是以对话框形式展现的

2.在POP02.cpp中和PROP03.cpp中同样加入这些代码

加上判断

判断用户是否输入数据

3.在PROP01.cpp中添加重写OnWizardNext()函数

LRESULT PROP01::OnWizardNext()
{
	UpdateData();
	if (m_lang==-1)
	{
		MessageBox(_T("请选择开发语言"),
            _T("开发语言未选择"), MB_OK | MB_ICONERROR);
		return -1;
	}
	if (m_company.GetLength()==0)
	{
		MessageBox(_T("请选择公司"),
             _T("公司未选择"), MB_OK | MB_ICONERROR);
		return -1;
	}
	return CPropertyPage::OnWizardNext();
}

在处理向下导航按钮的事件时阻止用户导航到下一页,则需要在 OnWizardNext() 中返回一个特定的值 -1

OnWizardNext() 是点击“下一步”按钮时触发的函数,它是 CPropertySheet 对象的一个成员函数

在PROP02.cpp中加入如下代码

LRESULT PROP02::OnWizardNext()
{
	bool haschose = false;
	UpdateData();
	for (int i=0;i<4;i++)
	{
		if (m_skill[i] == true)
		{
			haschose = true;
			break;
		}
	}
	if (!haschose)
	{
		MessageBox(_T("技能未选择"),
            _T("请选择技能"),MB_OK|MB_ICONERROR);
		return -1;
	}
	return CPropertyPage::OnWizardNext();
}

在PROP03中加入如下代码

BOOL PROP03::OnWizardFinish()
{
	UpdateData();
	if (m_money.GetWindowTextLength() == 0)
	{
		MessageBox(_T("薪资范围未选择"),
             _T("请选择薪资"), MB_OK | MB_ICONERROR);
		return FALSE;
	}
	return CPropertyPage::OnWizardFinish();
}

注意,这里返回值是0,而不是-1,因为这个函数返回值为bool型

消息反馈给用户

if (ID_WIZFINISH == dlg.DoModal())
	{
		CString strmsg = __T("您的选择是");
		switch (dlg.m_prop01.m_lang)
		{
		case 0:
			strmsg += __T("开发语言:C++");
			break;
		case 1:
			strmsg += __T("开发语言:java");
			break;
		case 2:
			strmsg += __T("开发语言:python");
			break;
		}
		strmsg += __T("您的公司是") + dlg.m_prop01.m_company;
		strmsg += __T("您的技能是");
		CString strSkill[4] = { __T("网络编程")
		, __T("MFC") , __T("操作系统") , __T("数据结构") };
		for (int i=0;i<4;i++)
		{
			if (dlg.m_prop02.m_skill[i])
			{
				strmsg += strSkill[i] + __T(",");
			}
		}
		
		strmsg += __T("您的薪资范围是") + dlg.m_prop03.text;
		MessageBox(strmsg, __T("最终信息"));
	}

ID_WIZFINISH 是在MFC中预定义的常量,表示“完成”按钮被点击

你可能感兴趣的:(C++大一下学期之MFC,mfc,c++)