之前学习MFC的时候就是三天打鱼两天晒网,什么都不记,脑子也不转,完全是代码的搬运工。这次又要从头开始,索性写个博客了。截至目前断断续续更了三十篇blog,文笔依然如此拙劣,实属羞愧。技术尚且肤浅,表达间歇性障碍。若有不到之处,还请各位看官见谅。本着菜鸟精神,一步一步的记载。大神请移步。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
系统:win10 64位、visual studio 2013
没有vs2013的童鞋请在这里下载:
链接:https://pan.baidu.com/s/1K74efwL5rSyONF7VS1IRMQ
提取码:pb7k
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
参考blog:https://blog.csdn.net/wang18323834864/article/details/78621633
做一个简单的加法计算器
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
一、搭建界面
首先要新建一个项目,选择MFC应用程序,名字自己起
然后点击确定,下一步,选择基于对话框模式的应用程序,如下
这时候在类视图下可以看到系统自动创建了三个类,分别是CAboutDlg、CAdditionApp和CAdditionDlg。CAboutDlg是应用程序的“关于”对话框,CAdditionApp是由CWinApp派生的类,CAdditionDlg是主对话框类,主对话框也就是此应用程序运行后显示的主要界面。
在资源视图下可以看到工程Addition的资源树,展开Addition.rc,下面有Dialog、Icon、String Table、和Version,分别是对话框、图标、字符串表和版本。
我们可以看到Dialog下面有两个对话框模板:IDD_ABOUTBOX、IDD_ADDITION_DIALOG,另外一个是后期加的,后面会讲到。第一个是“关于”对话框的模板:
后者是对话框的模板。ID是资源的唯一表示,一般ID代表的整数值由系统定义。
现在我们要把IDD_ADDITION_DIALOG这个对话框模板变成如下的形式,该如何去做呢?
操作很简单,找到工具箱,在工具箱内拉取文本框和控件以及button就可以了,如下:
“被加数”、“加数”、“和”这些都是静态文本框,它们后面跟的都是Edit Control,而计算就是Button,退出按钮是系统自动生成的。举个例子,我把Static Text选中以后,按住鼠标左键拖动到对话框中后,右键属性,得到如下面板:
也就是Caption可以改动自己给起个名字,其他的一些东西暂时可以不改,想具体了解功能的可自行百度。
给ID起名字的时候一定要有规律的起名字,不然到处混乱项目大起来就找不到了。。。。所有的静态框起的名字分别是: IDC_SUMMAND_STATIC、IDC_ADDEND_STATIC、IDC_SUM_STATIC
所有的控件起的ID名字分别是:IDC_SUMMAND_EDIT、IDC_ADDEND_EDIT、IDC_SUM_EDIT
计算这个按钮的ID是:IDC_ADD_BUTTON
这样界面就搭好了。因为项目Addition是基于对话框的程序,所以程序自动创建了对话框模板IDD_ADDITION_DIALOG,并自动生成了对话框类CAdditionDlg它是从CDialogEx类派生的,在vs2010中,一般对话框类都是继承自CDialogEx类。
二、为界面控件添加变量
搭建完界面以后其实并没有什么卵用,因为根本没有传值操作,也无法进行计算。我们需要把代码计算和MFC界面联系起来。
静态文本框只是起一个说明数据的意义,基本不会变,所以不用管。重点是后面编辑框的数据,是我们要填入的数值。
首先为被加数的编辑框IDC_SUMMAND_EDIT添加变量,选中编辑框,右键添加变量,变量名为m_editSummand,类的成员变量名一般以m_打头,以标识它是一个成员变量:
以此类推,给 IDD_ADDEND_EDIT添加double型变量m_editAddend、给IDD_SUM_EDIT添加double型变量m_editSum。在MFC机制中,控件和变量之间是怎样同步传值的呢?这是通过MFC对话框类自动生成的成员函数DoDataExchange()来实现的,也叫做对话框的数据交换和检验机制。我们进入到AddtionDlg.cpp中查看CAdditionDlg类中的DoDataExchange()函数的语句,这是自动生成的:
void CAdditionDlg::DoDataExchange(CDataExchange* pDX)
{
//处理MFC默认的数据交换
CDialogEx::DoDataExchange(pDX);
//处理控件IDC_SUMMAND_EDIT和变量m_editSummand之间的数据交换
DDX_Text(pDX, IDC_SUMMAND_EDIT, m_editSummand);
//处理控件IDC_ADDEND_EDIT和变量m_editAddend之间的数据交换
DDX_Text(pDX, IDC_ADDEND_EDIT, m_editAddend);
//处理控件IDC_SUM_EDIT和变量m_editSum之间的数据交换
DDX_Text(pDX, IDC_SUM_EDIT, m_editSum);
}
注意一点,在数据交换中,DoDataExchange()并不是被自动调用的,而是需要我们在程序中调用CDialogEx::UpdateData()函数,由UpdateData()函数再去自动调用DoDataExchange()的。
三、为控件添加消息处理函数
创建完对话框类和添加控件变量完事儿了,但是还是不能运行滴!因为我们还需要为控件添加消息处理函数。这是MFC的核心。
MFC为对话框和控件等定义了诸多消息,对它们操作时会触发消息,这些消息最终由消息处理函数处理。比如点击按钮时会产生BN_CLICKED消息,修改编辑框内容时会产生EN_CHANGE消息等,为了实现自己的效果,我们就需要实现相关消息处理函数。
首先,添加消息处理函数。我们在“计算”按钮上右键,添加事件处理程序,事件处理函数名叫做OnBnClickedAddButton:
然后代码就自动在AdditionDlg.cpp中生成了,如下:
void CAdditionDlg::OnBnClickedAddButton()
{
// TODO: 在此添加控件通知处理程序代码
//将各控件中的数据保存到相应的变量
UpdateData(TRUE);
//将被加数和加数的加和赋值给m_editSum
m_editSum = m_editSummand + m_editAddend;
//根据各变量的值更新相应的控件。和的编辑框会显示m_editSum的值
UpdateData(FALSE);
}
这时候这个小项目就能够运行啦!
拓展:
关于加法计算器的tab顺序问题,按快捷键ctrl+D就能看到tab顺序,按照自己的想法依次点击即可。
原文博主还讲解了模态对话框和非模态对话框。为了加深理解,我依然进行了操作。
四、添加自定义的对话框
Windows对话框分为两类:模态对话框和非模态对话框。所谓模态对话框就是当它弹出后,该应用程序其他窗口将不再接受用户输入,只有该对话框响应用户输入,在对它进行相应操作退出后,其他窗口才能继续与用户交互。非模态对话框就是,当它弹出后,本程序其他窗口仍能响应用户输入。非模态对话框一般是用来显示提示信息等。加法计算器实际上就是一个模态对话框。
模态对话框是怎么弹出来的呢?这个要看Addition.cpp文件,可以看到CAdditionApp类有个InitInstance()函数:
BOOL CAdditionApp::InitInstance()
{
// 如果一个运行在 Windows XP 上的应用程序清单指定要
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControlsEx()。 否则,将无法创建窗口。
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// 将它设置为包括所有要在应用程序中使用的
// 公共控件类。
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
// 创建 shell 管理器,以防对话框包含
// 任何 shell 树视图控件或 shell 列表视图控件。
CShellManager *pShellManager = new CShellManager;
// 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
// 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
//定义对话框类CAdditionDlg的对象dlg
CAdditionDlg dlg;
//将dlg设为主窗口
m_pMainWnd = &dlg;
//弹出对话框dlg,并将DoModal函数的返回值(退出时点击按钮的ID)赋值给nResponse
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: 在此放置处理何时用
// “确定”来关闭对话框的代码
}
else if (nResponse == IDCANCEL)
{
// TODO: 在此放置处理何时用
// “取消”来关闭对话框的代码
}
else if (nResponse == -1)
{
TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");
TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
}
// 删除上面创建的 shell 管理器。
if (pShellManager != NULL)
{
delete pShellManager;
}
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。
return FALSE;
}
能够看出来,其实弹出对话框的关键函数就是DoModal()函数。我们做个实验来加深一下对这个函数的了解。就是为加法计算器程序添加一个对话框,以在计算之前询问用户是否确定要进行计算。 步骤如下:
1.添加Dialog模板,在资源视图下右键Dialog,插入Dialog,然后声明它的ID为IDD_TIP_DIALOG
2.对这个自定义的模板进行一波骚操作,改变界面
3.为该对话框创建类,选中对话框右键添加类即可,之前我们没有添加类是因为计算器那个对话框的类已经被系统自动生成了--CAdditionDlg。
我们发现有.h和.cpp文件了。我们的想法就是用户点击“计算”的时候弹出这个对话框,然后用户在这个对话框上点击“确定”的时候才得到结果,如果用户点击取消就不得到结果。
4.添加消息处理函数
肯定还是“计算”这个按钮需要改动消息处理函数,需要在这个函数里构造CTipDlg类的对象tipDlg,然后通过tipDlg.DoModal()弹出对话框,最后判断DoModal()函数的返回值是IDOK还是IDCANCEL来确定是否继续进行计算。函数如下:
void CAdditionDlg::OnBnClickedAddButton()
{
// TODO: 在此添加控件通知处理程序代码
//用于保存DoModal函数的返回值
INT_PTR nRes;
//构造对话框类CTipDlg
CTipDlg tipDlg;
//弹出对话框
nRes = tipDlg.DoModal();
if (IDCANCEL == nRes)
return;
UpdateData(TRUE);
m_editSum = m_editSummand + m_editAddend;
UpdateData(FALSE);
}
然后你会发现可以控制啦!好神奇的说呢~~
感谢参考blog的博主,让我学到了很多~ღ( ´・ᴗ・` )比心