1.MFC基础(一)程序流程

一、MFC的概念和作用

  1.什么是MFC?

    全称为Microsoft Fundation Class Library我们称之为微软基础类库

    (1)从硬盘的存在形式来说MFC就是一个库(静态库)

    (2)从原理上来说MFC还是一个程序框架

  2.为什么使用MFC?

    基于框架编程提高工作效率,减少开发周期,降低开发成本

二、几个重要头文件

  afx.h - 包含了绝大部分MFC库中的类和声明

  afxwin.h - 包含了afx.h和windows.h

  afxext.h - 包含了关于扩展窗口类声明,例如:工具栏、状态栏等

  附:以Afx开头的函数就可以确定是MFC库中封装的全局函数

    以::开头的函数就可以确定是win32的API函数(user32.dll/kernel32.dll/gdi32.dll)

三、MFC应用程序类型

  1.使用MFC库制作自己的控制台程序

    (1)多了全局对象CWinApp theApp

    (2)入口函数不同于win32的入口函数

  2.使用MFC库制作自己的静态库程序

  3.使用MFC库制作自己的动态库程序

    (1)使用(静态/动态)MFC库制作自己的规则动态库程序

    (2)使用MFC制作自己的扩展库

       规则动态库可以被任何程序调用,扩展动态库库只能被支持MFC的程序调用

  4.使用MFC库制作自己的窗口程序

    (1)单文档视图构架程序

       CFrameWnd - 框架窗口类,封装了关于框架窗口的操作

       CWinApp - 应用程序类,负责管理程序的流程

       CDocument - 文档类,封装了关于数据的操作(提取/转换/存储数据)

       CView - 视图窗口类,封装了关于视图窗口的操作(显示数据)

    (2)多文档视图构架程序

       CMDIChildWnd - 子框架窗口,封装了关于子框架窗口的操作

       CMDIFrameWnd - 主框架窗口类,封装了关于主框架窗口的操作       

       CWinApp - 应用程序类,负责管理程序的流程

       CDocument - 文档类,封装了关于数据的操作(提取/转换/存储数据)

       CView - 视图窗口类,封装了关于视图窗口的操作(显示数据)

    (3)对话框构架程序

       CWinApp - 应用程序类,负责管理程序的流程

       CDialog - 对话框窗口类,封装了关于对话框窗口的操作

四、MFC库中类概述

  1. CObject - MFC库中绝大部分类的基类

    运行时类信息机制 / 动态创建机制 / 序列化机制

  2. CCmadTarget - 消息映射的最基类

  3. CWinThread / CWinApp - 应用程序类

  4. CDocument及其子类 - 文档类,负责管理数据

  5. Exceptions - 异常处理类,封装了MFC各种异常的处理

  6. CFile及其子类 - 文件操作类,封装了关于各种文档的读写等操作

  7. CWnd - 所有窗口类的最基类

  8. FrameWindows - 框架窗口类,封装了关于各种框架窗口的操作

  9. DialogBoxes - 对话窗口类,封装了关于各种对话框串口的操作

  10. Views - 视图窗口类,封装了关于各种视图窗口的操作

  11. Controls - 控件窗口类,封装了关于各种控件窗口的操作

  12. CDC及其子类 - 封装了各种绘图设备,以及绘图函数

  13. CGdiObject及其子类 - 封装了关于各种GDI绘图对象的操作

  14. CArray / CMap / CList及其子类 - 封装了C++语法中相应的数据结构

  15. 非CObject类 - 对各种结构进行了封装

    例如:CPoint / CRect / CTime / CString

五、第一个MFC程序

  1.配置环境

   (1)删除入口函数WinMain

   (2)将头文件<windows.h>改为<afxwin.h>

   (3)属性->常规中设置为使用MFC库(静态库动态都可以)

  2.代码

   (1)从CFrameWnd类派生了一个自己的框架窗口类CMyFrameWnd

   (2)从CWinApp类派生了一个自己的应用程序类CMyWinApp,并在类中重写了父类的虚函数InitInstance

   代码: 

#include "stdafx.h"


class CMyFrameWnd : public CFrameWnd  { };

class CMyWinApp : public CWinApp  
{
public:
    CMyWinApp();
    virtual BOOL InitInstance();
};

CMyWinApp::CMyWinApp() { }

CMyWinApp theApp;

BOOL CMyWinApp::InitInstance()
{
    CMyFrameWnd *pFrame = new CMyFrameWnd;
    pFrame->Create(NULL, L"MFCBase");
    m_pMainWnd = pFrame;
    pFrame->ShowWindow(SW_SHOW);
    pFrame->UpdateWindow();
    return TRUE;
}

六、程序的执行过程

  1.构造theApp

   (1)将theApp的地址保存到当前程序线程状态信息中

   (2)将theApp的地址保存到当前程序模块状态信息中  

   (3)AfxGetApp() / AfxGetThread() - 返回theApp的地址

    伪代码:

    AFX_MODULE_STATE    g_ModuleState;  //当前程序模块状态信息(MFC中的全局变量,我这里的变量名是随便起的)

    AFX_MODULE_THREAD_STATE   g_ThreadState;  //当前程序线程状态信息

    CWinApp::CWinApp( ... ) //构造theApp对象

    {

      //获取全局变量&g_ModuleState,AfxGetModuleState(); 

      AFX_MODULE_STATE* pMoudleState = _AFX_CMDTARGET_GETSTATE();  

      //获取全局变量&g_ThreadState,可以看出m_thread是g_MouleState的成员

      AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;  

      //将&theApp保存到pThreadState的成员变量中

      pThreadState->m_pCurrentWinThread = this;   

      CWinThread* AFXAPI AfxGetThread( )
      {
        AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState( );  //获取全局变量&g_MoudleThreadState
        CWinThread* pThread = pState->m_pCurrentWinThread;  //从g_MoudleThreadState取出&theApp赋值给pThread
        return pThread;  
      }

      pModuleState->m_pCurrentWinApp = this;  //将&theApp保存到g_ModuleState的成员中

      CWinApp* AfxGetApp( )

      {

        return  afxCurrentWinApp;  //宏替换为:AfxGetModleState( )->m_pCurrentWinApp,返回&theApp

      }

    }

  2.进入入口函数(WinMain),开始程序流程

   (1)获取theApp对象的地址

   (2)利用theApp调用应用程序类成员虚函数InitApplication(初始化)

   (3)利用theApp调用应用程序类成员虚函数InitInstance(创建并显示窗口)

   (4)利用theApp调用应用程序类成员虚函数Run(消息循环)

      如果没有消息,利用theApp调用应用程序类成员虚函数OnIdle(空闲处理)

      如果有WM_QUIT消息,利用theApp调用应用程序类成员虚函数ExitInstance(善后处理)

   伪代码:

    WinMain( ... )

    {

      AfxWinMain( ... )

      {       

        CWinThread* pThread = AfxGetThread( );  //返回theApp的地址
        CWinApp* pApp = AfxGetApp( );  //返回theApp的地址

        pApp->InitApplication( );  //利用theApp调用应用程序类成员虚函数(初始化)

        pThread->InitInstance( )  //利用theApp调用应用程序类的成员虚函数

        {

          //回到自己的代码

        }

        pThread->Run( )  //利用theApp调用应用程序类的成员虚函数(消息循环),函数内部this为theApp的地址

        {

          CWinThread::Run( )  //函数内部this为theApp的地址

          {

            while  ( 没有消息 )

            {

              OnIdle( );  //利用theApp调用应用程序类的成员虚函数(空闲处理)

            }

            do

            {

              if  (  GetMessage捕获WM_QUIT )  

                return  ExitInstance( );  //利用theApp调用应用程序类的成员虚函数(善后处理)

            } while ( ... );   

          }

        }

      }

    }

七、CWinApp成员虚函数

  目前为止我们知道的虚函数:

  InitApplication / InitInstance / Run / OnIdle / ExitInstance

原文地址:https://www.cnblogs.com/csqtech/p/5674996.html