动手学MFC之六——不止一个对话框

有些东西不动手是学不会的,比如MFC。

Ok,上一节需要你们动手了,那么我再推荐一些工具,和VC++6.0配套的有一个帮助文档MSDN,装上它之后,哪个系统函数不知道什么意思,把光标定位在上面,点击F1,就会弹出帮助哦,真正做到了哪里不会点哪里!还有一个就是VC助手,有了它,VC就像我们肚子里的蛔虫一样,我们刚敲出前面几个字母,它就给我们补全了,很好用哦!这些东西的安装这里就不讲了,百度一下一大把,当然,大家在学习过程中有什么问题也要学会百度,毕竟自己学会了学习才是最重要的。

好了,扯远啦,这次我们要学习的是,在对话框中再弹出对话框,而且是我们自定义的对话框,不是消息框哦!

学习的时候总得做点有意思的东西,这次我们要做的是一个简单的人员信息管理程序,在对话框里面有一个列表框,还有一个添加按钮,点击添加后,弹出另一个对话框,可以填入人员信息,填好后,点击ok,会将信息添加到列表框里面。

废话不多说,先把界面做出来。


         把添加按钮的ID改为IDC_BUTTON_ADD,把列表框的ID改为IDC_LIST_PERSON。给列表框关联一个CListBox的变量m_personList,注意,这时要在Category中选择Control,这是一个控件变量。


         下面我们再插入一个对话框,点击Insert->Resource


         在弹出的对话框中选择Dialog,点击New


         这时候出现一个新的对话框,同时,左边的资源视图也多了一个IDD_DIALOG1。


         修改新Dialog的ID为IDD_DIALOG_PERSON,Caption改为“添加人员”。

         将界面改为如下形式


并且将姓名后面的Edit的ID改为IDC_EDIT_NAME,年龄后面的Edit的ID改为IDC_EDIT_AGE,单选按钮男的ID改为IDC_RADIO_MALE,并勾选Group,单选按钮女的ID改为IDC_RADIO_FEMALE,多选按钮足球的ID改为IDC_CHECK_FOOTBALL,多选按钮篮球的ID改为IDC_CHECK_BASKETBALL,多选按钮乒乓球的ID改为IDC_CHECK_TABLETENNIS。

         点击View->ClassWizard,这时会弹出


   

这是因为我们新建了一个对话框,类向导询问我们是否要为新的对话框关联一个类。点击ok,为这个类取个名字CPersonDlg,点击ok


为该对话框的控件关联变量如下:


         到此,界面部分就全部弄好了。切换到FileView,我们会看见多了个PersonDlg.h和PersonDlg.cpp,这就是刚刚那个对话框所对应的类了。

         我们为添加按钮添加一个单击事件响应函数,在这个函数里弹出新的对话框。写上代码:

CPersonDlg personDlg;
         personDlg.DoModal();



         第一句话定义一个对话框类的对象,第二句话调用对象的DoModal方法,这个方法会产生一个模态对话框。这里补充一下,对话框分为两种,模态对话框和非模态对话框,它们有很多不同,不过最主要的区别就是模态对话框弹出之后,你不能再去点击该程序的别的地方了,必须先处理了这个模态对话框,才能点击程序的其他地方,而非模态对话框就没有这个限制。由于模态对话框比较简单,所以这里先讲模态对话框。

         编译一下吧,有4个错误


         这是因为我们还没有添加头文件,所以报错CPersonDlg是未定义的类型。

         在AnotherDialogDlg.cpp的前面加上#include"PersonDlg.h"


         编译运行,这时候就能成功了。点击一下添加,是不是弹出了对话框呢?

         但是我们填入数据后,点击ok没有反应,因为还没有加业务逻辑嘛,我们先把填入的数据取出来,将添加按钮的函数里面代码修改如下:

CPersonDlg personDlg;
         if(IDOK == personDlg.DoModal())
         {
                   CString info;
                   info.Format("姓名:%s,年龄:%d,",personDlg.m_name,personDlg.m_age);
                   if(0 == personDlg.m_sex)
                   {
                            info += "性别:男,";
                   }
                   else if(1 == personDlg.m_sex)
                   {
                            info += "性别:女,";
                   }
                   if(!personDlg.m_basketball&& !personDlg.m_football && !personDlg.m_tabletennis)
                   {
                            info += "爱好:无";
                   }
                   else
                   {
                            info += "爱好:";
                            if(personDlg.m_basketball)
                            {
                                     info +="篮球";
                            }
                            if(personDlg.m_football)
                            {
                                     if(personDlg.m_basketball)
                                     {
                                               info+= ",";
                                     }
                                     info +="足球";
                            }
                            if(personDlg.m_tabletennis)
                            {
                                     if(personDlg.m_basketball|| personDlg.m_football)
                                     {
                                               info+= ",";
                                     }
                                     info +="乒乓球";
                            }
                   }
                   MessageBox(info);
         }


         好了,希望你没有晕,这里稍微解释一下:

第二句的if里面,如果用户在弹出的对话框中点击了OK按钮,会返回IDOK,用户点击CANCEL会返回IDCANCEL,如果用户取消我们当然不要做任何事情啦!这里为什么把IDOK写在前面呢,这是一个良好的编程习惯,也是一个常见的面试题,因为初学者经常把==判断写成=,例如i=1,如果在if语句中写了这样一句话,那么if语句永远为真,编译期间检查不出这个错误,只能靠程序员去排查,当你检查了一小时发现原来是这里少写了一个=,估计要吐血了,这就是程序员为什么会猝死~~所以我们要养成良好的习惯,写成1==i,这时候如果误写成1=i,编译就过不去,我们根据编译错误就能很快发现问题啦~

第三句我们定义了一个CString的对象,CString这个类是对字符串的封装,功能非常强大,待会儿大家就体会到了。

第四句,我们把name和age放到info字符串里面了,这里用到了CString的Format方法,还记得printf函数吗?这个方法和那个函数差不多,只不过printf是将数据按照一定格式输出到屏幕上,而CString的Format方法是将数据按照一定格式输出到字符串里。其实将数据按照一定格式输出有一个专有名词,就是大名鼎鼎的格式化,format也就是格式化的意思。这句话就可以说是将name和age格式化一下。

personDlg.m_name是新开对话框的用户输入的姓名,m_name是我们为Edit控件关联的成员变量,但是同时别忘了,它也是CPersonDlg类的一个成员变量,只不过是一个特殊的成员变量,所以它也能像普通成员变量一样取出来。

接下来就是逻辑了,大家应该都能看懂了。还有一点说一下,字符串拼接的时候我们用了info += str,这是因为CString类重载了+=操作符,所以我们可以这样用,它的作用是将str字符串拼接到info后面,非常方便。

好了,编译一下,试一试,是不是弹出了我们要的信息呢。

接下来就是把这个信息添加到ListBox里面了,很简单,将MessageBox(info);替换成m_personList.AddString(info);,这句话的意思是将info字符串作为一个项目(item)添加到ListBox中。

试一试吧,我们编程的时候最好是编一点调试一点,像刚刚,先把info弹出来看看,确认无误后再进行添加。如果一开始就将代码全部写完,很可能调试起来会非常费劲。

这个程序还有一点不方便,就是新开的对话框没有默认值,我们想让它点开时姓名默认是无名氏,年龄默认18,性别默认男,怎么办呢?

打开PersonDlg.cpp,我们看到它的构造函数如下:

CPersonDlg::CPersonDlg(CWnd*pParent /*=NULL*/)
         : CDialog(CPersonDlg::IDD, pParent)
{
         //{{AFX_DATA_INIT(CPersonDlg)
         m_basketball = FALSE;
         m_football = FALSE;
         m_tabletennis = FALSE;
         m_age = 0;
         m_name = _T("");
         m_sex = -1;
         //}}AFX_DATA_INIT
}


         看到了吧,我们可以在这里修改它的初始值,但是一般我们不这么做,对话框在初始化的时候会产生一个消息WM_INITDIALOG,系统会调用它的事件响应函数,我们在那里面修改默认值。


         在函数中添加

m_age = 18;
         m_name = "无名氏";
         m_sex = 0;
         UpdateData(FALSE);



         好了,在运行一下吧,看看效果是不是好多了呢?

         可能有人注意到了,我们在OnInitDialog方法中调用了UpdateData(FALSE),将变量值传给控件显示出来,而在DoModal的时候并没有调用UpdateData(TRUE),来将控件值传递给变量,为什么后来能够取出来值呢?这是因为在调用DoModal的时候,系统会先将关联变量的值传到控件上,然后再显示对话框,同样,当用户将对话框关闭时(点击ok),系统会将控件上的值传回给关联变量。有人又回问了,既然这样为什么在OnInitDialog方法中还要调用UpdateData(FALSE)呢?这是因为OnInitDialog的调用发生在系统将关联变量的值传到控件上之后。你可以试试在CPersonDlg类的构造函数中改变默认值,那个时候不用调用UpdateData(FALSE)。下面的图清楚地解释了原因。


         好了,又到了总结知识点的时间了。这次我们学会了

1、  怎么给程序添加对话框

2、  怎么将其作为模态对话框弹出

3、  怎么初始化对话框上面的默认值以及将其值取回

4、  编程规范IDOK == personDlg.DoModal()

5、  CString类的简单使用

6、  ListBox简单使用

7、  程序编写调试小技巧

8、  WM_INITDIALOG消息和OnInitDialog响应函数

收获颇丰啊,希望大家回去后能够给程序添加一个小功能,实现一个删除按钮,点击后弹出一对话框,在里面输入号码,就删除对于的项目(item),比如输入1,就删除第一条项目。

本节的例子在http://download.csdn.net/detail/yeluoxiang/6940039,欢迎大家下载!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值