《MFC》(一)-----------2013.8.23
一、概念
一 MFC概念和作用
1 什么是MFC?
全称 Microsoft Foundation Class Library,我们称之为微软基础类库, 封装了 大量的类,封装了WINDOWS Api,还封装了C++语法的数据结构。
1 MFC就是一个库(静态库/动态库)
2 MFC还是一个应用程序框架
2 为什么使用MFC?
基于框架,使用MFC库,进行快速开发 减少开发周期,降低开发成本。
二 头文件
afx - application framework X
afx.h - 包含了 绝大部分MFC的头文件
afxwin.h - 包含了 afx.h 和 windows.h
afxext.h - 包含了对扩展窗口类的支持 例如:工具栏和状态栏等.
.
三 调用MFC库 可以实现的应用程序的类型
1 调用MFC库 实现自己的控制台程序
多了一个全局变量 CWinApp theApp;
入口函数 不同于 以往的控制台程序的入口函数(多了一个参数)
AfxWinInit - 初始化MFC库。
以 Afx....开头的函数 基本确定为MFC库内封装的全局函数
以::....开头的函数 完全确定为 window API 函数
2 调用MFC库 实现自己的库程序
2.1 调用MFC库 制作自己的静态库程序
2.2 调用MFC库 制作自己的动态库程序
2.2.1 规则库
调用静态MFC库 制作自己的规则动态库
调用动态MFC库 制作自己的规则动态库
2.2.2 扩展库
规则库 任何程序都可以调用, 扩展库 只能被支持MFC
的程序调用
3 调用MFC库 实现自己的窗口程序
3.1 单文档视图构架程序
CFrameWnd - 框架窗口类,负责管理框架窗口。
CWinApp - 应用程序类,负责管理整个程序的执行流程。
CDocument - 文档类,负责管理数据(提取/转换/存储)
CView - 视图窗口类,负责管理显示数据。
3.2 多文档视图构架程序
CMDIChildWnd - 子框架窗口类,负责管理子框架窗口。
CMDIFrameWnd - 主框架窗口类,负责管理主框架窗口。
CWinApp - 应用程序类,负责管理整个程序的执行流程。
CDocument - 文档类,负责管理数据(提取/转换/存储)。
CView - 视图窗口类,负责管理显示数据。
3.3 对话框构架程序
CWinApp - 应用程序类,负责管理整个程序的执行流程。
CDialog - 对话框类,负责管理对话框。
四 MFC库的类的结构
1 CObject - MFC库中绝大部分类基类,封装了MFC最基本机制
动态创建机制
运行时类信息机制
序列化机制
2 CCmdTarget - 消息映射机制的最基类
3 CWinThread/CWinApp - 应用程序类,负责程序的执行流程
4 CDocTemplate及其子类 - 文档模板类
5 CDocument及其子类 - 文档类,负责管理数据
6 Exceptions - 异常处理类,封装了MFC中常见各种异常处理。
7 CFile及其子类 - 文件操作类,封装了对硬盘文件I/0操作。
8 CWnd - 所有窗口类的最基类
9 CFrameWnd及其子类 - 框架窗口类,封装了对各种框架窗口的操作
10 CSplitterWnd - 不规则框架窗口类,用于切分窗口。
11 ControlBars - 控件栏类
12 Property Sheets - 属性表单类。
13 CDialog及其子类 - 对话框类,封装了对各种对话框的操作
14 Controls - 控件类,封装了各种控件的操作。
15 CView及其子类 - 视图窗口类,封装对各种视图窗口的操作
16 CDC/CGdiObject - 绘图操作的封装
17 CList/CArrary/CMap - 对C++语法中数据结构进行封装
非CObject类 - 对数据结构进行封装
例如:CPoint/CRect/CString/CTime.....
五 第一个MFC程序
1 环境配置
1.1 将入口函数WinMain删除,因为MFC中已经将入口函数进行
封装。
1.2 将头文件 更改为<afxwin.h>
1.3 Project-->Settings菜单项中设置 使用MFC库
2 代码的书写
2.1 从CFrameWnd类派生自己的框架窗口类 CMyFrameWnd
2.2 从CWinApp类派生自己的应用程序类CMyWinApp
重写 CWinApp成员虚函数InitInstance,在这个函数中
注册窗口类/创建窗口/显示窗口/刷新窗口
3 程序的执行流程
3.1 构造 theApp对象 执行 CWinApp类的构造函数
将theApp对象地址保存到 当前程序模块状态信息中
将theApp对象地址保存到 当前程序线程状态信息中
AfxGetThread/AfxGetApp - 返回theApp对象地址.
3.2 进入入口函数WinMain,调用AfxWinMain
3.3 AfxWinMain函数的内部执行流程
3.3.1 获取 应用程序类的全局对象 theApp的地址。
3.3.2 调用 应用程序类的成员虚函数InitApplication初始化应用
程序。
3.3.3 调用 应用程序类的成员虚函数InitInstance 注册窗口类,
创建并显示窗口
3.3.4 调用 应用程序类的成员虚函数Run实现消息循环
1)如果没消息调用应用程序类的成员虚函数OnIdle空闲
处理
2)调用 应用程序类的成员虚函数PumpMessage实现提取/
翻译/派发 消息
3)调用 应用程序类的成员虚函数ExitInstance实现善后处
理
六 CWinApp的成员(运行时接触到的成员函数)
1 成员虚函数
InitApplication
InitInstance
Run
OnIdle
PumpMessage
ExitInstance
2 普通成员(运行时接触到的成员变量)
m_pMainWnd - 保存的是 主框架窗口类 对象地址
stdafx.cpp
#include "stdafx.h"
class CMyFrame : public CFrameWnd
{
public :
};
class CMyWinApp : public CWinApp
{
public :
CMyWinApp();
virtual BOOL InitInstance();
};
CMyWinApp theApp;
CMyWinApp::CMyWinApp()
{
}
BOOL CMyWinApp::InitInstance()
{
CMyFrame* pFrame = new CMyFrame();
pFrame->Create(NULL,"MFC");
pFrame->ShowWindow(SW_SHOW);
pFrame->UpdateWindow();
m_pMainWnd = pFrame;
return TRUE;
}
在构造上打上断点
进入CWinApp构造函数内部
伪代码
AFX_MODULE_STATE aaa;//当前程序模块状态信息(全局变量)
AFX_MODULE_THREAD_STATE bbb;//当前程序线程状态信息(全局变量)
CWinApp::CWinApp(..)
{
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
//返回全局变量 &aaa
AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;
//返回全局变量 &bbb
pThreadState->m_pCurrentWinThread = this;
//将 &theApp保存到全局变量 bbb的一个成员中
AfxGetThread()
{
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
//获取全局变量 &bbb
CWinThread* pThread = pState->m_pCurrentWinThread;
//重新获取 &theApp
return pThread;
}
pModuleState->m_pCurrentWinApp = this;
//将 &theApp 保存到全局变量 aaa的一个成员中
AfxGetApp()
{
return AfxGetModuleState()->m_pCurrentWinApp;
//返回 &theApp
}
}
MFC程序运行流程
在初始化函数上打上断点,通过调用堆栈可以知道调用过InitInstance函数的函数,进入AfxWinMain函数。
继续进入AfxWinMain函数中的Run函数
继续进入CWinThread::Run()函数
继续进入PumpMessage函数