目录
当点开新建项目选项卡面板,没有MFC应用的,看这里
菜单栏——工具——(第一个选项)获取工具和功能(T)
选中工作负荷中的使用C++的桌面开发——详细安装选择MFC
执行修改,等待安装即可
1.VS2017菜单栏文件——新建——项目
2.项目面板选择VSC++选项下的MFC应用,并且选择文件位置及项目名称
3.应用程序类型选择——基于对话框——点击下一步
4.模板属性不用管,下一步
5.界面功能,默认,不用管,下一步
6.之后的一直按照默认的来,最后点完成,完成创建
1.创建好项目之后,打开资源视图(资源视图打开方法:菜单栏视图——其他窗口——资源视图(R)),资源视图,.rc后缀的文件夹下——点开Dialog文件夹——点开IDD_***_DIALOG
左边大方框部分就是我们的Dialog对话框,之后的拖入控件Button的操作都要从这里入手
2.对话框中间蓝色虚线围起来的部分是展示内容的区域,我们写入代码,拖入控件显示任何东西都在这里(显示区域),上方一般是放菜单或者工具的地方左上角的工具箱可以拖入控件,比如button按钮(这里跟C#几乎一毛一样)——工具箱找不着看这里:菜单栏——视图——工具箱
在做案例之前,先把对话框中原来的(确定,取消,button全部delete删除掉)此处可用ctrl+a&delete大法
我们的目标界面是有两个button,实现模态对话框(有了它之后你只能先把这个弹出的对话框叉掉才能点电脑的其他区域)和非模态对话框(这个button弹出的对话框不是最优先级的,可以点击电脑的其他地方)
工具箱中找到button,直接鼠标左键拖入可视区域想要放置的区域,两个哦(也可以Ctrl+C&Ctrl+V大法把刚拖入的控件粘贴)
左键单击选中控件,右键弹出选项中选择最底下的属性,属性面板中找到Caption把Button1改为模态对话框改好后单击空白的地方结束输入
此方法也适用于改整个对话框的名字,修改对话框属性的Caption改为自己想要的名字
写在前面:此方法改完后千万别双击button2
虽然在C++图形库QT中可以双击改控件名,但在MFC中千万别用(会后悔的~)
左键单击选中button2,直接输入想要的名字:非模态对话框,确认输入后可以回车,但千万别双击,因为双击后会生成一个时间代码,并且由对话框编辑器跳转至代码
打开资源视图,点开.rc后缀名文件下的子文件夹Dialog右键——插入Dialog(E)
他的默认名字是(ID)是IDD_DIALOG1
这个DIALOG1我们即将把它作为,点击第一个(我们拖了两个控件button的对话框)点击点击模态对话框之后弹出的对话框,IDD_DIALOG1是刚创建的对话框的ID名,我们可以修改他的属性——ID,改为:IDD_EXEC,因为在QT中模态叫做EXEC,这里可以随便改,后续写函数会用到对话框的ID,最好起一个符合其内容的ID
给IDD_EXEC拖入一个button改Caption为:生成模态显示框了
如法炮制另一个对话框,ID改为IDD_SHOW,button的Caption为生成非模态显示框了
上述对话框就像是QT中的ui文件,就只是一个框架,要想让框架可以执行某些功能,就得插入相应的.h或者.cpp文件对ui文件进行关联
右键对话框面板,添加类,起个类名:CDialogExec,点击确定,弹出一个CDialogExec.h文件
且在类视图(菜单——视图——类视图可以打开)里生成了一个CDialogExec的类
那是怎么和IDD_EXEC对话框 联系起来的呢?点开CDialogExec::__unnamed_enum_027a_1(位置如下图)
可以看到enum枚举的是我们刚刚修改好的dialog对话框的ID,如果这一行有红色下划波浪线(报红,可以忽略)那是因为我们修改了对话框ID编译器还没反应过来
现在,模态对话框已经通过枚举ID关联起来了
这里所说的主对话框是两个BUTTON的那个
我们要写一个单击button就可以弹出相应对话框的功能
我们需要给button写入事件,事件button的属性中,闪电图标下的BN_CLICKED事件,其右边的小三角形,点开会有一个
void Cpra01Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
}
这个就是我们刚刚添加的时间代码,目前是空实现
第二种添加事件方法是选中控件,右键——添加事件处理程序——类列表:默认不要动;消息类型:BN_CLICKED
最后一种添加事件的方法就是双击控件——简单粗暴,生成事件代码(默认情况是单击事件)
现在有两个button的事件代码了
在模态对话框单击事件的函数模板里写入CDialogExec类的实现代码,既然是类,又不在本文件中,那么就得引用CDialogExec的头文件,但是这里和其他C++编译场景不同的是,如果类名字的第一个字母是大写的C,则引用头文件时要省略C引用头文件
//如果去掉C报错就加上C
写入如下单击事件代码
- //模态对话框按钮的单击事件
- void Cpra01Dlg::OnBnClickedButton1()
- {
- // TODO: 在此添加控件通知处理程序代码
- //创建CDialogExec对象
- CDialogExec dlg;//创建对象dlg
- dlg.DoModal();//生成模态对话框用DoModal()函数
- }
运行试一下,除非把模态对话框点掉,否则无法进行其他操作
和模态对话框IDD_EXEC同样的步骤关联非模态对话框IDD_SHOW
引用头文件
写入button2单击事件函数代码
- //非模态对话框按钮的单击事件
- void Cpra01Dlg::OnBnClickedButton2()
- {
- // TODO: 在此添加控件通知处理程序代码
- //弹出非模态对话框
- //创建CDialogShow对象
- CDialogShow dlg;
- //显示对话框
- dlg.Create(IDD_SHOW);//用creat函数,传入要创建的对话框的ID
- dlg.ShowWindow(SW_SHOWNORMAL);//显示对话框,传入参数是SW_DENORMAL意思是Normal显示
- //ShowWindow的父类是CWnd,鼠标停靠在showWindow那里会有小字提示,然后在根据提示找
- }
此时运行非模态对话框点开只会一闪而过
问题在哪儿?
观察,分析,我们的模态和非模态对话框的事件都是一个局部的方法,方法的代码就那么几行,事件代码运行完了,窗口也完了
那么为什么模态对话框那里没有一闪而过?
那是因为DoModal()起到了阻塞作用
那么要解决一闪而过的问题就只能把它引诱到堆区(堆区是由程序员决定释放的,堆区的概念可以看之前写在C++专栏的四区文章)
还有一个方法呢就是把CDialogShow dlg写到CDialogShow类的成员函数里面,延长生命周期
在类视图里找到Cpra01Dlg类,这是整个MFC对话框的类,在这里面添加CDialogShow dlg;为私有变量,此时,记得添加CDialogShow的头文件(并且要把写单击事件里创建的对象CDialogShow dlg;代码注释掉,否则运行会报错)按照截图对应着来
运行成功,不是一闪而过
还有一个更简单的方法是,在创建的CDialogShow dlg对象前面加上static放入全局区,延长生命周期,只简单的加一个static也可以改变非模态对话框的命运
最后,退掉非模态对话框第二次点击的时候程序就崩掉了,因为我们的dlg.Create(IDD_SHOW);//只能用一次(在这里)第二次点击就没有再creat了
解决方法就是,把这段代码放入构造函数中(不推荐,别问我为什么),放入同一个文件的OnInitDialog()函数中,这个函数前面的都不用看,找到后面的/ TODO: 在此添加额外的初始化代码,在这里creat窗口就可以反复调用了
此时报红,是因为我用的是改成static的方法,改用第一个方法,写到成员变量中就行了
如有不对的地方,烦请在评论区或者私信指教~
~--_^^_--~