MFC框架
- MFC框架
-
- 一、什么是MFC?
- 二、MFC的用途
- 三、MFC的应用程序的类型
- 四、MFC主要的类
- 五、第一个MFC程序
- 六、MFC的入口函数(程序启动)机制
- 七、MFC程序的执行过程
- 八、应用程序类CWinApp的总结
- 九、MFC的窗口创建机制
- 十、MFC的消息映射
- 十一、MFC菜单
- 十二、MFC工具栏
- 十三、MFC状态栏
- 十四、CDialogBar 类
- 十五、MFC的视图
- 十六、MFC的视图
- 十七、运行时类信息
- 十八、动态创建
- 十九、MFC的切分窗口
- 二十、MFC的文档
- 二十一、文档模板类
- 二十二、使用文档模板类创建多文档视图程序
- 二十三、使用文档模板创建多文档视图程序
- 二十四、MFC绘图
- 二十五、文件操作
- 二十六、序列化
- 二十七、对象的序列化
- 二十八、MFC对话框
- 二十九、对话框数据交换技术
- 三十、MFC的各种控件
- 三十一、树控件
- 三十二、Tab控件
- 三十三、MFC的多线程
- 三十四、企业的上机题
- 三十五、基于windows平台的数据库访问技术
- MFC的第二部分
- MFC的第三部分
MFC的课程极强的连续性,不能缺课,不能走神
不但学习知识点多,更多的还需要掌握阅读代码的能力和调试代码的技巧
Windows平台上,继 Win32核心编程 之后的 基于MFC框架开发
MFC是封装了绝大部分的Win32 API之上的编程框架
QT 和 MFC 的联系区别?
QT是一个跨平台的开发框架,MFC是微软公司开发的专门基于Windows平台的开发框架
MFC框架
MFC课程组成:15天
- MFC的机制和原理
基于MFC的应用程序的组成部分(由哪些类组成)、执行流程、原理和机制。
例如:消息映射、运行时类信息、动态创建等 - Windows平台上的数据访问技术,包括ODBC、ADO
- Windows平台上的网络通信编程
- 项目
MFC的课程目标:
- MFC框架生成的程序的组成部分和执行流程
- MFC的机制
程序启动、窗口创建、消息映射(命令消息的路由)、运行时类信息、
动态创建 - 使用断点调试
F9、F5、F10、F11、shift+F5、Ctrl+F5 - 通过 调用堆栈 窗口查看函数的调用关系
- MSDN
一、什么是MFC?
Microsoft Foundation Classes: 微软基础类库
- 是一个庞大的类库
- 是一个应用程序的编程框架
二、MFC的用途
基于框架编程,提高开发效率,缩短开发周期,降低开发成本
三、MFC的应用程序的类型
窗口应用程序 , 直接面向用户的、双击就可以运行的程序
-
单文档程序 (4个类)只能管理一个文档
CAboutDlg --帮助菜单项下的 关于对应的对话框窗口 不是必须的
CWinApp 类 – 应用程序类,负责整个应用程序的管理
CFrameWnd类 – 单文档的框架窗口类
CView/CEditView类-视图类 – 视图窗口类,用来显示数据
CDocument类 – 文档类,用来管理数据,包括数据保存和加载
-
多文档程序 (5个类)可以管理多个文档
CWinApp类 – 应用程序类,负责整个应用程序的管理
CMDIFrameWnd类 – 多文档的主框架窗口类
CMDIChildWnd类 – 多文档的子框架窗口类
CViewCEditView类-视图类 – 视图窗口类,用来显示数据
CDocument类 – 文档类,用来管理数据,包括数据的保存和加载
-
基于对话框的程序
CWinApp类 – 应用程序类,负责整个应用程序的管理
CDialog/CDialogEx类 – 对话框类,创建对话框窗口
-
库程序 面向的用户是程序员
规则动态库
接口是规则的,可以被其它的C++程序使用
(1) 动态链接MFC库
(2) 静态链接MFC库
MFC扩展DLL
接口是MFC的,只能被MFC使用 -
控制台程序
四、MFC主要的类
-
CObject类
继承关系中的顶层父类。主要实现了MFC的一些特性和机制。例如:运行时类信息、动态创建和序列化。 -
CCmdTarget类
父类是CObject类,该类实现了对命令消息的处理 -
CWinApp类
应用程序类,管理整个应用程序的运行 -
CWnd类
父类是CCmdTarget类,提供了窗口的基本操作
几个不同类型的子类:框架窗口类、视图窗口类、对话框类、控件类、工具栏和状态栏 -
CDocument类
父类是CCmdTarget类,主要用来管理数据
CObject - CCmdTarget - CWinThread - CWinApp
|
|------- CWnd ------- CFrameWnd - CMDIFrameWnd
| | |---- CMDIChildWnd
| |
| |-- CView
| |
| |-- CDialog
| |
| |-- CButton、CEdit...
| |
| |-- CControlBar - CToolBar
| |------ CSuatusBar
|
|------- CDocument
-
CException类
异常处理类 -
CFile类、CFileFind类
文件操作类 -
CDC类、CGdiObject类及其子类
绘图设备和绘图对象类 -
MFC的集合类
CArray类、CList类、CMap类 -
非CObject类的子类
主要定义了在项目中常用的一些数据结构
例如:CString类、CTime类、CPoint类、CRect类、CSize等
五、第一个MFC程序
创建项目:
- 创建 win32桌面应用程序 -》设置项目属性:静态链接MFC \多字节字符集
- 在项目中添加cpp文件,文件名MFCbase.cpp.在文件中:
包含头文件,#include <afxwin.h> //win32 +mfc
添加应用程序类,CWinApp类的子类,并且添加全局的应用程序对象theApp
添加框架窗口类,CFrameWnd类的子类。
重写CWinApp::InitInstance()函数,在函数中,创建基本的窗口程序。
添加源文件
/*
#include <Windows.h> //Win32
#include <afx.h>
*/
#include <afxwin.h> //写这个已包含 MFC+WIN32
//2.单文档的主框架窗口类
class CMyFrameWnd :public CFrameWnd {
};
//1.应用程序类
class CMyWinApp :public CWinApp {
public:
//初始化操作,用户程序的代码由此开始编写和执行
virtual BOOL InitInstance();
};
CMyWinApp theApp; //全局的应用程序对象
BOOL CMyWinApp::InitInstance() {
//创建基本的窗口程序
CMyFrameWnd* pFrame = new CMyFrameWnd;
pFrame->Create(NULL, "MFCBase");
m_pMainWnd = pFrame;
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
运行测试:
Win32的方式:
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,
WPARAM wParam,LPARAM lParam)
{
switch(msgID){
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd,msgID,wParam,lParam);
}
int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevIns,
LPSTR lpCmdLine,int nCmdShow)
{
WNDCLASS wns = {
0};
wns.cbClsExtra = 0;
wns.cbWndExtra = 0;
wns.hCursor = NULL;
wns.hIcon = NULL;
wns.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wns.hInstance = hInstance;
wns.lpfnWndProc = WndProc;
wns.lpszClassName = "Main";
wns.lpszMenuName = NULL;
wns.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
RegisterClass(&wns);
HWND hWnd = CreateWindowE(0,"Main","Window",
WS_OVERLAPPEDWINDOW,
100,100,700,500,NULL,NULL,hInstance,NULL);
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
MSG nMsg = {
0};
while(GetMessage(&nMsg,NULL,0,0)){
TranslateMessage(&nMsg);
DispatchMessage(&nMsg);
}
return 0;
}
六、MFC的入口函数(程序启动)机制
与win32程序相同,MFC程序也是由WinMain函数开始执行,只不过,WinMain函数是由MFC框架在底层提供,用户不需要也不能再写WinMain函数。
VS调试相关快捷键:
F9- 设置/取消断点
F5 - 启动调试
Ctrl+F5 -执行程序(不调式)
Shift +F5 - 终止调试
F10 -单步调试,遇到函数调用,当成一条普通语句执行过去
F11 -单步调试,遇到函数调用,跳转到被调用函数内部执行
在调试状态下,调试窗口才能使用,其中一个 “调用堆栈” 窗口,作用是查看函数之间的调用关系
七、MFC程序的执行过程
( 底层代码+用户代码 )
程序启动,调用MFC框架提供的WinMain()函数,在函数中,调用AfxWinMain()函数后,
在函数中执行以下步骤:
- 调用AfxGetThread() 和AfxGetApp() 获取全局对象theApp的地址,分别保存在pThread 和 pApp中。
- 应用程序框架的内部初始化 和 应用程序的全局初始化
- 根据函数机制,调用到CMyWinAPP::InitInstance()虚函数,完成用户代码,创建并显示窗口
- 调用Run()函数,进入消息循环,当 点击关闭按钮时,产生WM_QUIT消息,调用ExitInstance()函数,释放和清理资源并返回。
- AfxWinMain()返回,WinMain()函数返回 ,程序结束。
在MFC程序中,通过大量的虚函数使得底层代码在执行时,可以调用到用户代码。
// 1. MFC框架提供的程序入口函数
WinMain(...)
{
AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
{
// 1 获取theApp的地址,并保存在pThread和pApp中
CWinThread* pThread = AfxGetThread();
CWinApp* pApp = AfxGetApp();
// 2 框架的内部初始化和应用程序的全局初始化
AfxWinInit(...);
pApp->InitApplication();
// 3 重写虚函数InitInstance,完成用户特定的初始化操作
pThread->InitInstance() -- 虚函数1
{
// 用户代码,按照程序员自己的需要编写代码,创建一个基本的窗口
return TRUE;
}
// 4 消息循环
pThread->Run() -- 虚函数2
{
CWinApp::Run()
{
CWinThread::Run()
{
for (;;)
{
// 4.1 没有消息时,作空闲处理
while(!::PeekMessage(...))
{
OnIdle(...); -- 虚函数3
}
// 4.2 有消息时,获取、翻译并派发消息
do{
if(!PumpMessage())
{
AfxInternalPumpMessage()
{
if(!::GetMessage(...))
return FALSE;
::TranslateMessage(...);
::DispatchMessage(...);
return TRUE;
}
}
// 退出前,调用ExitInstance函数
return ExitInstance(); -- 虚函数4
}while(::PeekMessage(...));
}
}
}
}
}
}
八、应用程序类CWinApp的总结
-
虚函数
- InitInstance()