zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    git代码冲突
    Centos Git1.7.1升级到Git2.2.1
    linux指定某非root用户执行开机启动项的方法(gogs git)
    kvm增加硬盘挂载
    git分支管理策略
    mac命令行配置网络
    svn稀疏目录--通过设置工作目录的深度(depth)实现目录树的部分签出
    svn update解决冲突
    rocketmq单机搭建
    MongoDB数据库未授权访问漏洞及加固
  • 原文地址:https://www.cnblogs.com/csqtech/p/5674996.html
Copyright © 2011-2022 走看看