几年前,写过一段时间的MFC,但是只知其然不知其所以然,最近闲来无事,研究了一下MFC程序的运行顺序,特此记录一下。

首先,如果我们创建一个MFC程序的话,首先会自动生成一个CWinApp的子类,程序运行时,最先执行的就是该子类的构造函数。

然后,会由连接器调用函数内自动连接的函数AfxWinMain,这个函数在文件winmain.cpp中实现,这也可以被作为整个MFC程序的入口函数,其代码如下:

int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow)
{
ASSERT(hPrevInstance == NULL); int nReturnCode = -1;
CWinThread* pThread = AfxGetThread();
CWinApp* pApp = AfxGetApp(); // AFX internal initialization
if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
goto InitFailure; // App global initializations (rare)
if (pApp != NULL && !pApp->InitApplication())
goto InitFailure; // Perform specific initializations
if (!pThread->InitInstance())
{
if (pThread->m_pMainWnd != NULL)
{
TRACE(traceAppMsg, 0, "Warning: Destroying non-NULL m_pMainWnd\n");
pThread->m_pMainWnd->DestroyWindow();
}
nReturnCode = pThread->ExitInstance();
goto InitFailure;
}
nReturnCode = pThread->Run(); InitFailure:
#ifdef _DEBUG
// Check for missing AfxLockTempMap calls
if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
{
TRACE(traceAppMsg, 0, "Warning: Temp map lock count non-zero (%ld).\n",
AfxGetModuleThreadState()->m_nTempMapLock);
}
AfxLockTempMaps();
AfxUnlockTempMaps(-1);
#endif AfxWinTerm();
return nReturnCode;
}

函数执行时,先通过AfxGetThread()和AfxGetApp()获取两个指针对象,这两个函数前者是获取当前运行的线程对象,后者是获取当前运行的APP对象,细心的话,可以发现CWinApp是继承自CWinThread类的,所以如果是单线程的应用的话,两者返回的应该是同一个对象指针,而这个对象正是我们前面所提到的CWinApp的子类。

于是一切都顺理成章了,首先调用InitApplication()函数,然后调用InitInstance()函数,最后调用Run()来接受界面上的消息进行相应的处理。

MFC程序运行原理初探的更多相关文章

  1. SpringBoot-02 运行原理初探

    SpringBoot-02 运行原理初探 本篇文章根据b站狂神编写 pom.xml 2.1.父依赖 其中它主要是依赖一个父项目,主要是管理项目的资源过滤及插件! <parent> < ...

  2. 孙鑫MFC学习笔记3:MFC程序运行过程

    1.MFC中WinMain函数的位置在APPMODUL.cpp APPMODUL.cpp中是_tWinMain,其实_tWinMain是一个宏#define _tWinMain WinMain 2.全 ...

  3. Java基础知识强化之多线程笔记05:Java程序运行原理 和 JVM的启动是多线程的吗

    1. Java程序运行原理:     Java 命令会启动Java 虚拟机,启动 JVM,等于启动了一个应用程序,也就是启动了一个进程.该进程会自动启动一个 “主线程” ,然后主线程去调用某个类的 m ...

  4. 第二章--Win32程序运行原理 (部分概念及代码讲解)

    学习<Windows程序设计>记录 概念贴士: 1. 每个进程都有赋予它自己的私有地址空间.当进程内的线程运行时,该线程仅仅能够访问属于它的进程的内存,而属于其他进程的内存被屏蔽了起来,不 ...

  5. QF——iOS程序运行原理(APP的生命周期)

    iOS程序的运行原理: main.m: 1. main.m 主函数是所有程序的入口函数. 2. 在main函数里是UIApplicationMain函数,开启了一个无限循环,以监听该应用. 该UIAp ...

  6. Python源代码剖析笔记3-Python运行原理初探

    Python源代码剖析笔记3-Python执行原理初探 本文简书地址:http://www.jianshu.com/p/03af86845c95 之前写了几篇源代码剖析笔记,然而慢慢觉得没有从一个宏观 ...

  7. .NET程序运行原理及基本概念详解

    一.引言 我们知道在Java中有虚拟机,代码运行时虚拟机把Java语言编译成与机器无关的字节码,然后再把字节码编译成机器指令执行,那么在.NET中程序是如何运行的呢?其实运行原理是一样的,.NET中的 ...

  8. 狂神说SpringBoot02:运行原理初探

    狂神说SpringBoot系列连载课程,通俗易懂,基于SpringBoot2.2.5版本,欢迎各位狂粉转发关注学习. 微信公众号:狂神说(首发)    Bilibili:狂神说Java(视频) 未经作 ...

  9. Java程序运行原理

    概念介绍: ![file](https://img2018.cnblogs.com/blog/1454321/202001/1454321-20200104145655999-149562495.jp ...

  10. MFC程序运行流程

    ->进入入口函数_tWinMain() 程序首先进入文件AppModul.cpp,找到_tWinMain()函数运行,调用其中的AfxWinMain()函数. 由于为了支持UNICODE,C运行 ...

随机推荐

  1. EveryCircuit_v2.15汉化破解版apk下载

    安卓手机扫码下载  大小 6.44M EveryCircuit(电子电路模拟器)是一个专为电子信息技术专业的人士所打造的软件,它能够让你轻松的了解到电子电路究竟是如何进行工作的. 下载地址:https ...

  2. P5318 【深基18.例3】查找文献题解(链式前向星)

    P5318 [深基18.例3]查找文献题解 用head记录这一起点的最后一条边, next记录这一起点的上一条边. 注意要按照参考文献的倒叙排序(要按顺序看,而链式前向星是逆着来的,也就是为什么最简单 ...

  3. Code Review在TDSQL-C 的应用实践

    1.1 为什么重视Code Review? 结合下面这个例子,我们来谈谈为什么要重视code review.假设你作为新人刚入职,领导分配了一个需求,于是接下来做了下面这些事: 为了完成任务疯狂敲了三 ...

  4. VUE学习-优化组件

    组件(优化) 动态组件 keep-alive 当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题. 有时我们更希望那些标签的组件实例能够被在它们第一次被创建的时候 ...

  5. CodeGym自学笔记02——打印命令

    1.方法的主体由命令组成.我们甚至可以说,方法就是一组被赋予名称(方法名称)的命令. 2.如果你使用几次 System.out.println() 命令,就会发现每次传递给该命令的文本都会显示在单独的 ...

  6. Mac OS 如何批量转换图片格式

    ​ 在苹果电脑中,如何快速批量地转换图片的格式.苹果电脑的预览程序,可以实现PNG.JPEG.JPEG-2000.PDF.TIFF格式之间的互换.这里以将PNG格式转换为JPEG格式为例. 工具/原料 ...

  7. 070_GET https://login.salesforce.com/17181/logo180.png 404 (Not Found)

    这个问题怎么解答? Google了一下:https://success.salesforce.com/answers?id=90630000000D6qzAAC 谷歌应用商店安装了一个 Resourc ...

  8. XXE漏洞初步练手

    0x00:XXE定义 xml外部实体注入被我们称为XXE.因为实体可以通过预定义在文档中被调用,而实体的标识符又可以访问本地或者远程内容,当允许引用外部实体时,攻击者便可以构造恶意内容来达到攻击.

  9. js-防抖(简易版)

    /**  * 节流函数  */ var count = 1; var container = document.getElementById('container'); function getUse ...

  10. 【SSO单点系列】(5):CAS4.0 之JDBC

    deployerConfigContext.xml 修改对应添加以下代码 <bean id="SearchModeSearchDatabaseAuthenticationHandler ...