以下内容为学习《鸡啄米MFC》的摘要,具体内容见鸡啄米教程:http://download.csdn.net/detail/u011642774/9640351
一、MFC应用程序的运行流程与SDK程序类似,都是先进行一些初始化过程,再注册并创建窗口,然后显示、更新窗口,最后进入消息循环,消息都由窗口过程函数处理。
二、框架中比较重要的类:
CHelloWorldApp类处理消息,将收到的消息分发给相应的对象;CMainFrame是视图CHelloWorldView的父窗口,视图CHelloWorldView就显示在CMainFrame的客户区中。视图类CHelloWorldView用来显示文档类CHelloWorldDoc中的数据,并根据对视图类的操作修改文档类的数据。一个视图类只能跟一个文档类相联系,而一个文档类可以跟多个视图类相联系。
三、消息映射机制
1.在MFC软件开发中,界面操作或者线程之间通信都会经常用到消息,通过对消息的处理实现相应的操作。比较典型的过程是:用户操作窗口→→有消息产生→→送给窗口的消息处理函数处理→→对用户的操作做出响应。
2.MFC使用一种消息映射机制来处理消息,在应用程序框架中的表现就是一个消息与消息处理函数一一对应的消息映射表,以及消息处理函数的声明和实现等代码。当窗口接收到消息时,会到消息映射表中查找该消息对应的消息处理函数,然后由消息处理函数进行相应的处理。
3.除了一些没有基类的类或CObject的直接派生类外,其他的类都可以自动生成消息映射表。下面的讲解都以前面例程HelloWorld的CMainFrame为例。消息映射表如下:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
ON_WM_CREATE()
ON_COMMAND(ID_VIEW_CUSTOMIZE, &CMainFrame::OnViewCustomize)
END_MESSAGE_MAP()
在BEGIN_MESSAG_MAP和END_MESSAGE_MAP之间的内容成为消息映射入口项。消息映射除了在CMainFrame的实现文件中添加消息映射表外,在类的定义文件MainFrm.h中还会添加一个宏调用:
DECLARE_MESSAGE_MAP()
4.添加消息处理函数(自动还是手动添加都有三个步骤):
a.在类定义中加入消息处理函数的函数声明。例如MainFrm.h中WM_CREATE的消息处理函数的函数声明:afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
b.在类的消息映射表中添加该消息的消息映射入口项。例如WM_CREATE的消息映射入口项:ON_WM_CREATE()。
c.在类实现中添加消息处理函数的函数实现。例如,MainFrm.cpp中WM_CREATE的消息处理函数的实现:
intCMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
......
}
通过以上三个步骤以后,WM_CREATE等消息就可以在窗口类中被消息处理函数处理了。
四、创建工程
文件--新建--新建项目--MFC应用程序--根据向导创建各类型的MFC
五、控件安放
使用什么控件,在Dialog界面,从工具箱中拖过来就行。
摆放位置调整:格式--各种对齐方式或“上下左右”箭头调整或使用相关函数(如:MoveWindow())
控件大小:鼠标单击控件,然后调整打下或“shift+上下左右箭头”
六、添加对话框并为对话框添加类
在ResourceView的“Dialog”节点上点右键,在右键菜单中选择“Insert Dialog”,就会生成新的对话框模板,并且会自动分配ID。其他资源的添加同理。在Resource View的资源树中双击某个ID,可在中间区域内显示相应的资源界面。例:双击IDD_ADDITION_DIALOG时,中间区域就会显示Addition对话框模板。
单击对话框--右键--添加类--选择基类的类型。添加完类后,会自动生成相关的.h和.cpp文件。
七、为控件添加成员变量
单击控件--右键--添加变量,根据需要添加控制型或数值型变量。(也可以在“类向导--添加成员变量”中实现)
八、数据交换机制
数据交换机制通过DoDataExchange()函数完成,DoDataExcheange()不是自动调用的,是通过UpdateData()函数调用的。
UpdateData(TRUE);//数据传输方向:控件→成员变量
UpdateData(FALSE);//数据传输方向:成员变量→控件
九、添加消息
在类向导中:可以添加系统消息、控件的触发消息。或控件右键或控件属性--控制事件
十、对话框中按Tab键控件的跳转顺序设置
在主菜单中选择“Format”->"TabOrder",或者按快捷键Ctrl+D,对话框模板上就会显示各个控件的Tab顺序数字。
修改方式:从自己认为Tab顺序应该为1的控件开始依次单击,随着单击的完成,各控件的Tab响应顺序也按我们的想法设置好了,然后按“Esc”键退出设置模式。
十一、对话框
Windows对话框分为两类:模态对话框和非模态对话框。
模态对话框是这样的对话框,当它弹出后,应用程序其他窗口将不再接受用户输入,只有该对话框响应用户输入,即:对它进行相应操作退出后,其他窗口才能继续与用户交互。
非模态对话框则是,它弹出后,本程序其他窗口仍能响应用户输入。非模态对话框一般用来显示提示信息等。
MFC中自动生成的代码:
1. CxxxDlg dlg; // 定义对话框类CAdditionDlg的对象dlg
2. m_pMainWnd = &dlg; // 将dlg设为主窗口
3. INT_PTR nResponse = dlg.DoModal(); // 弹出对话框dlg,并将DoModal函数的返回值(退出时点击按钮的ID)赋值给nResponse
4. if (nResponse == IDOK) // 判断返回值是否为OK按钮(其ID为IDOK,鸡啄米已经将它删除)
5. { …… }
6.else if (nResponse == IDCANCEL) // 判断返回值是否为Cancel按钮(其ID为IDCANCEL,鸡啄米将它的Caption改为了“退出”)
7.{ …….}
模态对话框的创建及弹出过程:
1.创建一个Dialog资源,并为此对话框A添加类(自动生成ADlg.h和ADlg.c文件)。
2.在需要弹出对话框A的对话框的.cpp文件中,添加ADlg.h头文件。
3.添加以下程序弹出对话框:
INT_PTR nRes; // 用于保存DoModal函数的返回值
CADlg tipDlg; // 构造对话框类CADlg的实例
nRes = tipDlg.DoModal(); // 弹出对话框
if (IDCANCEL == nRes) // 判断对话框退出后返回值是否为IDCANCEL,如果是则return,否则继续向下执行
return;
……
//非模态对话框:
1、在需要弹出对话框A的对话框的.h文件中,添加ADlg.h头文件。
2、类中添加private成员变量CTipDlg *m_pTipDlg;
3、在构造函数体中添加m_pTipDlg = NULL;
4、创建、显示:
// 如果指针变量m_pTipDlg的值为NULL,则对话框还未创建,需要动态创建
{
// 创建非模态对话框实例
m_pTipDlg = new CTipDlg();
m_pTipDlg->Create(IDD_TIP_DIALOG, this);
}
// 显示非模态对话框
5、因为此非模态对话框实例是动态创建的,所以需要手动删除此动态对象来销毁对话框。
在析构函数中:
CxxxDlg::~CxxxDlg()
{
// 如果非模态对话框已经创建则删除它
if (NULL != m_pTipDlg)
{
// 删除非模态对话框对象
delete m_pTipDlg;
}
}
此外,其他类型对话框还包括:
属性页对话框、向导对话框、消息对话框、字体/颜色/文件对话框