MFC 学习笔记(一):MFC单文档程序运行流程梳理与总结

MFC 学习笔记(一):MFC单文档程序运行流程梳理与总结

1.MFC单文档程序运行流程

1.首先利用全局变量对象 theApp 启动应用程序
(这是因为这个全局对象,基类CWinApp中 this 的指针才能指向这个对象。)

2.调用全局应用程序对象 theApp 的构造函数
(需要先调用其基类CWinApp的构造函数,
完成应用程序的一些初始化工作,并将应用程序对象的指针保存起来。)

3.进入WinMain函数
(CWinApp的构造函数中调用 AfxWinMain 函数)

4.调用虚函数:InitInstance()
(利用在AfxWinMain函数中可以获取子类的指针,并调用InitInstance函数 如下图)
(③ 指令实际上调用的是子类(CTestApp)的InitInstance函数)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.子类(CTestApp)中的InitInstance()函数完成应用程序的一些初始化工作
(包括窗口类的注册,创建,窗口的显示和更新。
期间会多次调用CreateEX函数,因为一个单文档MFC应用程序有多个窗口,包括框架窗口.工具条.状态条等。)

初始化举例
例如:
1)CTestApp::Initstance()函数中定义了一个单文档模板对象指针,
2)该对象就把文档类对象、框架类对象、视窗类对象有机地组织在一起,
3)接着利用AddDocTemplate函数把这个单文档模板添加到文档模板中,从而把这个三个类组织成为一个整体,如图:
在这里插入图片描述
又如:
1)m_pMainWnd 表示指向程序框架窗口的指针(CMainFrame)
2)通过该指针显示和更新程序框架窗口
在这里插入图片描述

4.进入消息循环。
上图:pThread->Run()
(虽然也设置了默认的窗口过程函数,但是,MFC应用程序实际上是采用消息映射机制来处理各种消息。当收到WM_QUIT消息时,退出消息循环,程序结束。)

参考博客:
https://blog.csdn.net/c_base_jin/article/details/52345563

PS:
1.Afx前缀的函数代表应用程序框架(Application Framework)函数,属于全局函数,它们可以在程序的任何地方被调用。
2.以域作用符“::”开始的表示的函数,表明该函数是一个全局函数。

2.总结补充

1.由于theApp是全局对象,因此会在进入WinMain()之前完成构造
theApp的构造动作会导致一系列的对theApp的初始化动作:

pModuleState->m_pCurrentWinApp = this;

2.接着进入WinMain()
WinMain()(_tWinMain(),这是为了UniCode而准备的一个宏)直接调用AfxWinMain(),AfxWinMain()发挥真正应该由WinMain()发挥的作用,它取得theApp,然后必须先调用AfxWinInit(),再用取得的指向theApp的指针pApp调用InitApplication()、InitInstance()和Run(),最后调用AfxWinTerm()终止程序。
即AfxWinMain()中的动作相当于:

AfxWinInit();
CWinApp::InitApplication();
CMyWinApp::InitInstance();
CWinApp::Run();

3.AfxWinInit()做什么?
首先将WinMain()传进来的四个参数保留在theApp的成员变量里。
调用AfxInitThread(),此函数又调用::SetWindowHookEx(),不知干啥。另外此函数还将消息队列尽量加大到96。

4.CWinApp::InitApplication()做什么?
会做一些与CDocManager()和Document Template相关的工作,是MFC的内部管理范畴。

5.CMyWinApp::InitInstance()做什么?
终于来到了我们可以改写的InitInstance(),这个函数是CWinApp的虚函数,CMyWinApp通常要改写它,其实在CWinApp中InitInstance()是一个空函数。
InitInstance()的动作如下:

m_pMainWnd = new CMyFrameWnd();
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();

【(InitInstance()首先会创建一个CMyFrameWnd对象,并将指针保留在m_pMainWnd中。这个CMyFrameWnd对象的创建过程就会导致主窗口的登记和建立,因为CFrameWnd的构造函数中会调用Create()函数,而这个函数负责创建窗口(通过调用CreateWindowEx),窗口风格使用最常见的WS_OVERLAPPEDWINDOW。
但是这仅仅是创建窗口,窗口类注册的动作(必须先于窗口的创建)又发生在哪里呢?
其实Create()的调用会导致CWnd::CreateEx()的调用,此函数才是真正调用CreateWindowEx()创建窗口者,在调用CreateWindowEx()之前会调用CFrameWnd::PreCreateWindow(),此函数判断传入的窗口类名lpszClassName是否为NULL,若是,则通过一系列的调用(非常之绕)为其注册默认窗口类别。由于每个窗口创建过程中PreCreateWindow()都只在创建之前被调用,因此窗口的注册大多在创建之前发生。CWnd及其派生类的各个不同)

PreCreateWindow()函数为不同窗口指定了不同的默认窗口类别:
CWnd使用的窗口类别是_afxWnd
CFrameWnd和CMDIChildWnd使用的窗口类别是_afxWndFrameOrView
CMDIFrameWnd使用的窗口类别是_afxWndMDIFrame】

综上,InitInstance()中的第一个动作――创建CMyFrameWnd对象――完成了窗口的创建。之后的动作就很直观了,ShowWindow()显示窗口,UpdateWindow()发送WM_PAINT消息更新窗口。

6.回到AfxWinMain()中,接下来执行的是CWinApp::Run()。
Run()所做的正是维持程序运行的“消息循环”。CWinApp::Run()会调用CWinThread::Run(),此Run()中有消息循环,通过PumpMessage()得到并转发消息(调用::GetMessage()、::TranslateMessage()、::DispatchMessage(),一如SDK!)。
**但是转发到哪里呢?窗口函数呢?**原来在MFC为我们注册默认窗口类的时候已经指定了窗口函数为DefWindowProc(),但是真正处理消息的又不是它,而是一个全局函数AfxWndProc(),这是MFC通过hook和subclassing技术做到的,暂且不提。

综上,MFC为我们的程序提供了WinMain()、注册了窗口类、创建了窗口甚至提供了窗口函数,留给我们做的只是写出响应消息的处理函数,而这些消息和处理函数如何对应起来还要靠MFC六大关键技术之一的Message Mapping(消息映射)消息映射机制的目的是首先搭建起消息和消息处理函数对应的大框架,再通过宏的机制让程序员能够方便地添加消息和消息处理函数之间的对应关系。

7.在程序运行的过程中,程序不断地由消息所驱动,直到用户动作发出了WM_CLOSE消息,程序即将关闭
过程是:由于CMyFrameWnd没有设立WM_CLOSE的处理函数,因此该消息被送往预设处理函数,预设函数对WM_CLOSE的处理是调用::DestroyWindow(),进而发送WM_DESTROY消息,WM_DESTROY消息同样会被送到预设处理函数,预设函数对WM_DESTROY的处理方法是调用::PostQuitMessage(),发送WM_QUIT,CWinApp::Run()在收到WM_QUIT后会结束自己的消息循环,并调用ExitInstance(),这是CWinApp的虚函数,可被CMyWinApp改写,调用过此函数后,回到AfxWinMain()中调用AfxWinTerm()结束程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/491304.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

对话清华教授孙茂松:第三代人工智能要处理“可解释性”问题

来源:澎湃新闻正如人类会综合利用视觉、听觉、触觉、语言等信息,让人工智能(AI)从多角度、多模态、多学科学习自然语言也是清华大学人工智能研究院的目标与任务。2019年7月1日,清华大学人工智能研究院第八个研究中心&a…

QT学习笔记(一):VS2013 +QT 5.8 运行、编译问题解决

QT学习笔记(一):VS2013 QT 5.8 运行、编译问题解决 jom: E:\C\4.QT\HelloWord\Makefile.Debug [debug\moc_predefs.h] Error 1 ‘cl’ 不是内部或外部命令,也不是可运行的程序 或批处理文件。 jom: E:\C\4.QT\HelloWord\Makefile…

使用清华镜像安装pytorch失败的解决方法

首先添加清华镜像至Anaconda仓库: conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ conda config --set show_channel_urls yes …

受精卵或非“生命起始”?网友:教材是不是要改了……

来源:中国新闻网一直以来,科学家们都认为,精卵结合受精以后就是生命。但是,最近中美胚胎学家的一项最新联合研究成果表明,人类受精卵存在两套独立纺锤体,即从精卵结合到发生第一次有丝分裂期间,…

利用Excel进行成对(配对)T检验

首先在Excel中添加数据分析工具 https://jingyan.baidu.com/article/c275f6ba74b69ee33d7567c8.html 在Excel添加要分析的两组数据: 点击数据——>数据分析,选择t-检验:平均值的成对二样本分析,分别选取两组要分析的数据和输…

垃圾要分类!我们的大脑如何处理垃圾呢?

来源:中国生物技术网最近,垃圾分类已经成了热点话题,但实行这一举措的最终目的还是为了保护我们赖以生存的地球环境。同样,大脑为了维持健康,也专门有一套自己的“垃圾清除系统”,即glymphatic(…

QT学习笔记(三):Qt软件打包发布(QT5.8 _msvc2013_64+Win10_64)

QT学习笔记(三):Qt软件打包发布(QT5.8 _msvc2013_64Win10_64)1.编译方式介绍:2.动态编译方式打包发布QT程序:方法一:手动复制方法二:使用工具问题&解决:环…

麦肯锡报告摘译:未来成功城市的14个特征

来源:TOP产业办公研究院【前言】:本文摘译自麦肯锡发布的一份研究报告。报告来源:McKinsey&Company Report: Thriving amid turbulence: Imagining the cities of the future. Authored by Jonathan Woetzel , Vineet Rajadhyaksha , Joe…

MATLAB编辑GUI界面

在命令窗口输入:guide 即可进入编辑 若要在GUI界面的一个面板上显示程序中随意给定的字符: 首先创建一个“可编辑文本”(位于左侧工具栏): 双击该面板,弹出该面板的工具栏,设置“string”&am…

单个神经元不可靠!这项新研究推翻以往认知,感知的最大限制在于解码过程...

来源:凹非寺“单个神经元不可靠!”一项关于神经元的研究,让众人看嗨了。这项研究通过在小鼠身上做实验,先展示了神经元“不靠谱”的一面:单个神经元两次对相同视觉刺激的反应,竟然是不一样的。对于神经元的…

(转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在

问题描述:在用vs生成MVC时若使用Internet应用程序为模版,项目建好后重新编译下无法通过,弹出错误: 解决方案:问题出来后,询问了身边很多人都是一头雾水,于是乎各种谷歌和百度,还好功…

QT学习笔记(四):Qt5+MSVC编译 中文字符显示乱码问题解决

QT学习笔记(四):Qt5MSVC编译 中文字符显示乱码问题解决问题:1、解决方法一:2、解决方法二:3、解决方法三:4、解决方法四:结果显示:Qt5MSVC编译 中文字符显示乱码。 现在为…

github单独下载某个文件或文件夹

首先下载tortoiseSVN,安装好之后打开github项目的地址,例如https://github.com/rbgirshick/fast-rcnn 单独下载某个文件夹: 如果只需要下载tools这个文件夹, 点进这个文件夹,复制该页面的网址得到https://github.com/…

技术架构大迁徙时代来临,10个关键点读懂数字化转型

来源:THINKTANK新智囊2月,在旧金山举办的IBM Think 2019大会上,IBM CEO、总裁及董事长Ginni Rometty提出当前正在进入数字化重塑2.0阶段(Digital Reinvention, Chapter II):数字化重塑的第二篇章&#xff0…

QT学习笔记(五):Qt5的8种标准对话框示例

QT学习笔记(五):Qt5的8种标准对话框示例前言实例展示1.颜色对话框2.文件对话框3.字体对话框4.输入对话框5.消息对框6.进度对话框7.错误信息对话框8.向导对话框.前言 QT 提供了常用的对话框类型,他们全部继承自QDialog类&#xff…

张亚勤、刘慈欣、周鸿祎、王飞跃新书推荐,《崛起的超级智能:互联网大脑如何影响科技未来》...

《崛起的超级智能:互联网大脑如何影响科技未来》2019年7月由中信出版社出版,前沿科技趋势研究专家,计算机博士刘锋著。张亚勤、刘慈欣、周鸿祎、王飞跃、约翰翰兹推荐!吕乃基、石勇、吕本富做序。《崛起的超级智能:互联…

ARM与RISC-V之争,后起之秀的优势在哪儿?

来源:朗锐智科从2010年夏天开始,伯克利研究团队大约花了四年的时间,设计和开发了一套完整的新的指令集。这个新的指令集叫做RISC-V,指令集从2014年正式发布之初就受到多方质疑,到2017年印度政府表示将大力资助基于RISC…

道阻且长,Libra 项目负责人长文回应一切质疑

来源:星球日报当地时间 7 月 3 日,Facebook Libra 项目负责人 David Marcus 于个人 Facebook 发布长文《Libra, 2 weeks in》,就过去两周 Libra 所遇到的一些质疑及误解进行解释。以下为全文内容:自 Libra 正式公开已经两周了&…

QT学习笔记(七):定时器事件的3种常用使用方式

QT学习笔记(七):定时器事件的2种常用使用方式 Qt中定时器的使用有2种方法:一种是使用QObject类提供的定时器通过重载 timerEvent 事件处理过程函数,一种就是使用QTimer类。 其中QTimer 类来实现定时器使用的更多&…

LightOJ - 1140 How Many Zeroes?

Description Jimmy writes down the decimal representations of all natural numbers between and including m and n, (m ≤ n). How many zeroes will he write down? Input Input starts with an integer T (≤ 11000), denoting the number of test cases.Each case cont…