一个简单的MFC加法器

前些天,根据vs2010之MFC入门到精通文档,跟着写了下一到十六节的一个程序。

下面是我在写的过程中觉得需要自己注意的:

一、MFC消息映射机制

 一个消息与消息处理函数一一对应的消息映射表,以及消息处理函数的声明和实现等。

消息映射表:

  如下所示:

BEGIN_MESSAGE_MAP(CAdditionDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_ADD_BUTTON, &CAdditionDlg::OnBnClickedAddButton)
	ON_BN_CLICKED(IDC_INSTRUCT_BUTTON, &CAdditionDlg::OnBnClickedInstructButton)
END_MESSAGE_MAP()

在BEGIN_MESSAGE_MAP与END_MESSAGE_MAP之间的内容也可称之为消息映射入口项,一般在其头文件中会添加一个宏调用:DECLARE_MESSAGE_MAP.


添加消息处理函数包括三个步骤:

1、在类定义中加入消息处理函数的函数声明,注意要以afx_msg打头。

// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	afx_msg void OnBnClickedAddButton();

2、 在类的消息映射表中添加该消息的消息映射入口项。

BEGIN_MESSAGE_MAP(CAdditionDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_ADD_BUTTON, &CAdditionDlg::OnBnClickedAddButton)
	ON_BN_CLICKED(IDC_INSTRUCT_BUTTON, &CAdditionDlg::OnBnClickedInstructButton)
END_MESSAGE_MAP()

3、 在类实现中添加消息处理函数的函数实现。

void CAdditionDlg::OnBnClickedAddButton()

这里注意下自定义消息的定义;


二、添加控件变量(这里控件为Edit control)

 1.在编辑框上点右键,在右键菜单中选择“Add Variable”。弹出添加成员变量的向导对话框。

  2.我们想为其添加值变量而不是控件变量,所以对话框中“Category”下的组合框中选择Value

  3.“Variable type”下的组合框此时默认选中的是“CString”CString是字符串类,显然不能进行加法运算。我们可以选择doublefloatint等。这里我们选择double,即编辑框关联一个double类型的变量。

  4.“Variablename”中写入自定义的变量名。鸡啄米为其取名m_editSummand


在程序运行界面中,用户往往会改变控件的属性,例如,在编辑框中输入字符串,或者改变组合框的选中项,又或者改变复选框的选中状态等。控件的属性改变后MFC会相应修改控件关联变量的值。这种同步的改变是通过MFC为对话框类自动生成的成员函数DoDataExchange()来实现的,这也叫做对话框的数据交换和检验机制。

添加了控件变量后DoDataExchange中变化为:

void CAdditionDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);

	//处理控件IDC_SUMMAND_EDIT与m_editSummand之间的数据交换
	DDX_Text(pDX, IDC_SUMMAND_EDIT, m_editSummand);
	DDX_Text(pDX, IDC_ADDEND_EDIT, m_editAddend);
	DDX_Text(pDX, IDC_SUM_EDIT, m_editSum);
}


这种数据交换机制中,DoDataExchange()并不是被自动调用的,而是需要我们在程序中调用CDialogEx::UpdateData()函数,由UpdateData()函数再去自动调用DoDataExcha

nge()。

CDialogEx::UpdateData()函数的原型为:

BOOL UpdateData(BOOL bSaveAndValidate = TRUE);
参数:bSaveAndValidate用于指示数据传输的方向,TRUE表示从控件传给变量,FALSE表示从变量传给数据。默认值是TRUE,即从控件传给变量。
返回值:CDialogEx::UpdateData()函数的返回值表示操作是否成功,成功则返回TRUE,否则返回FALSE。


三、改变控件TAB顺序

在菜单栏中格式下选择。


四、模态对话框与非模态对话框

1、模态对话框

    先建立一个Dialog,并生成一个dialog类。

       /*INT_PTR nRes;

	CTipDlg tipDlg;

	nRes = tipDlg.DoModal();

	if (IDCANCEL == nRes)
	{
		return;
	}*/

2、非模态对话框

 同样建立一个Dialog,并生成一个dialog类。

//private:
//	CTipDlg *m_pTipDlg;

在源文件构造函数中初始化。

CAdditionDlg::CAdditionDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CAdditionDlg::IDD, pParent)
	, m_editSummand(0)
	, m_editAddend(0)
	, m_editSum(0)
	/*, m_pTipDlg(NULL)*/
在消息处理函数中实现:

/*if(NULL == m_pTipDlg)
	{
	m_pTipDlg = new CTipDlg();

	m_pTipDlg->Create(IDD_TIP_DIALOG, this);
	}

	m_pTipDlg->ShowWindow(SW_SHOW);*/

最后在析构函数下释放指针。


五、属性页对话框

属性页对话框,用到的类主要有两个:CPropertyPage类和CPropertySheet类。


1、CPropertyPage 类继承自 CDialog 类,它被用于处理某单个的属性页,所以要为每个属性页都创建一个继承自 CPropertyPage 的子类。

CPropertyPage类提供了一些消息处理函数,来响应属性页对话框的各种消息。我们重载这些消息处理函数,就可以自定义对属性页对话框操作的处理。

可重载的消息处理函数包括:
OnApply:处理属性页的“Apply”按钮被单击的消息
OnCancel:处理属性页的“Cancel”按钮被单击的消息
OnKillActive:处理属性页当前活动状态被切换的消息,常用于数据验证
OnOK:处理属性页的“OK”按钮、“Apply”按钮或者“Close”按钮被单击的消息
OnQueryCancel:处理属性页的“Cancel”按钮被单击前发出的消息
OnReset:处理属性页的“Reset”按钮被单击的消息
OnSetActive:处理属性页被切换为当前活动页的消息
OnWizardBack:处理属性页的“Next”按钮被单击的消息,仅在向导对话框中有效
OnWizardFinish:处理属性页的“Finish”按钮被单击的消息,仅在向导对话框中有效
OnWizardNext:处理属性页的“下一步”按钮被单击的消息,仅在向导对话框中有效

2、CPropertySheet类继承自CWnd类,它是属性表类,负责加载、打开或删除属性页,并可以在属性页对话框中切换属性页,它跟对话框类似,也有模态和非模态两种。

参数dwFlags:

设置向导按钮的外观和功能属性。可以是以下值的组合:
PSWIZB_BACK 启用“Back”按钮,如果不包含此值则禁用“Back”按钮。
PSWIZB_NEXT 启用“Next”按钮,如果不包含此值则禁用“Next”按钮。
PSWIZB_FINISH 启用“Finish”按钮。
PSWIZB_DISABLEDFINISH 显示禁用的“Finish”按钮。

参数nButton:

要模拟按下的按钮,它可以是下列值之一:
PSBTN_BACK 选择“Back”按钮。
PSBTN_NEXT 选择“Next”按钮。
PSBTN_FINISH 选择“Finish”按钮。
PSBTN_OK 选择“OK”按钮。
PSBTN_APPLYNOW 选择“Apply”按钮。
PSBTN_CANCEL 选择“Cancel”按钮。
PSBTN_HELP 选择“帮助”按钮。

3、创建属性页对话框资源

在“Resource View”的Dialog”节点上点右键,然后在右键菜单中选择“Insert Dialog”创建第一个对话框模板,对话框的ID属性设置为IDD_SUMMAND_PAGE,Caption属性改为“被加数页”,Style属性在下拉列表中选择“Child”,Border属性在下拉列表中选择“Thin”。

这里要注意Style属性选择“Child”。


4、创建属性页类


在“Class name”编辑框中输入类名“CSummandPage”,与之前不同的是,因为属性页类都应继承于CPropertyPage类,所以要修改下面“Base class”的选项,在下拉列表中选择“CPropertyPage”。

因为是第一个属性页,所以它应该有一个“下一步”按钮,CPropertyPage类的可重载函数中,OnSetActive函数用于处理属性页被切换为当前活动页的消息,所以我们可以在OnSetActive函数中进行相关设置。

在类视图下,选属性下的重载。

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

//BOOL CAddPage::OnSetActive()
//{
//	// TODO: 在此添加专用代码和/或调用基类
//
//	CPropertySheet* psheet = (CPropertySheet*) GetParent();
//
//	psheet->SetFinishText(_T("完成"));
//
//	return CPropertyPage::OnSetActive();
//}
//
//
//BOOL CAddPage::OnWizardFinish()
//{
//	// TODO: 在此添加专用代码和/或调用基类
//
//	MessageBox(_T("使用说明向导已阅读完!"));
//
//	return CPropertyPage::OnWizardFinish();
//}

5、创建属性表类

SolutionExplorer视图中的根节点“Addition”上点右键,在右键菜单中选择Add->Class,弹出“Add Class”对话框,然后在中间区域中选择“MFC Class”,点“Add”按钮,弹出另一个类向导对话框,设置Class nameCAddSheetBaseclass选择“CPropertySheet”,点“Finish”按钮,这样就属性表类就建好了。

       接下来,在新生成的AddSheet.h中包含三个属性页类的头文件:

       #include"SummandPage.h"
       #include "AddendPage.h"
       #include "AddPage.h"

       之后在AddSheet.h中添加private变量:

      CSummandPage    m_summandPage;
       CAddendPage    m_addendPage;
      CAddPage        m_addPage;

       然后在AddSheet.cpp文件中修改CAddSheet的两个构造函数为:

CAddSheet::CAddSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
	:CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
{

	AddPage(&m_summandPage);
	AddPage(&m_addendPage);
	AddPage(&m_addPage);
	

}

CAddSheet::CAddSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
	:CPropertySheet(pszCaption, pParentWnd, iSelectPage)
{
	AddPage(&m_summandPage);
	AddPage(&m_addendPage);
	AddPage(&m_addPage);
	
}

这里顺序别写错了,会影响程序运行。

最后在消息处理函数中添加:

void CAdditionDlg::OnBnClickedInstructButton()
{
	// TODO: 在此添加控件通知处理程序代码

	CAddSheet sheet(_T(""));

	/*sheet.SetWizardMode();*/

	sheet.DoModal();
}

当然也可有另一种属性表:

将之前的重载函数都注释,

在消息处理函数中添加:

void CAdditionDlg::OnBnClickedInstructButton()
{
	// TODO: 在此添加控件通知处理程序代码

	CAddSheet sheet(_T(""));

	

	sheet.DoModal();
}

六、消息对话框

一个简单的MFC加法器_第1张图片

你可能感兴趣的:(一个简单的MFC加法器)