Visual Studio 2022的MFC框架——theApp全局对象

这篇具有很好参考价值的文章主要介绍了Visual Studio 2022的MFC框架——theApp全局对象。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Visual Studio 2022的MFC框架——theApp全局对象,Visual Studio技术,visual studio,mfc,c++,microsoft,windows

 

我是荔园微风,作为一名在IT界整整25年的老兵,今天我们来重新审视一下Visual Studio 2022下开发工具的MFC框架知识。 

MFC中的WinMain函数是如何与MFC程序中的各个类组织在一起的呢?MFC程序中的类是如何与WinMain函数关联起来的呢?

面对这个问题,我们来分析一下。

双击我在我的《Visual Studio 2022的MFC框架——应用程序向导》一文中的项目例子中的类视图窗口中的CMfcApp类,跳转到该类的定义文件(Mfc.h)中。可以发现CMfcApp派生于 CWinApp类,后者表示应用程序类。

我们在类视图窗口中双击该类的构造函数,就跳转到该类的源文件(Mfc.cpp)中。在CMfcApp构造函数处设置一个断点,然后调试运行Mfc程序,将发现程序首先停在CMfcApp类的构造函数处,继续运行该程序。

这时程序才进入WinMain函数,即停在先前我在我的《Visual Studio 2022的MFC框架——WinMain函数》一文中的WinMain函数中设置的断点处。

按我们过去在C/C++编程的理解中,WinMain函数是程序的入口函数。也就是说,程序运行时首先应该调用的是WinMain函数,那么为什么这里程序会首先调用CMfcApp类的构造函数呢?

看一下CMfcApp的源文件,可以发现在程序中定义了一个CMfcApp类型的全局对象:theApp。代码如下。

//唯一的 CMfcApp对象

CMfcApp theApp;

MFC程序的全局变量都放置在类视图窗口中的“全局函数和变量”分支下,单击该分支即可看到程序当前所有的全局函数和变量。双击某个全局变量,即可定位到该变量的定义处。

在这个全局对象定义处设置一个断点,然后调试运行Mfc程序,将发现程序执行的顺序依次是:

1.theApp全局对象定义处

2.MfcApp构造函数

3.WinMain函数。

为了更好地解释这一过程,我们在项目解决方案下,添加一个新的“Windows控制台应用程序”项目,该项目的名称为:findwm。

接下来,在findwm.cpp文件中输入如下所示的代码。

#include "pch.h"
#include <iostream>

using namespace std; 

int s=100;

int main()

{

cout<<s<<endl;

return 0;

}

上述代码首先定义了一个int类型的全局变量s, 并给它赋了一个初值100。然后在main函数中将全局变量s的值输出到标准输出cout上。

将该项目设置为启动项目, 然后在main函数处设置一个断点, 调试运行该程序, 将会发现程序在进入main函数时, s的值已经是100了。在程序入口main函数加载时,系统就已经为全局变量或全局对象分配了存储空间,并为它们赋了初始值。

接下来,把全局变量s换成一个全局对象,看看结果如何。修改代码, 新定义一个CPoint类, 并定义该类的一个全局变量pt。

#include"pch.h"
#include<iostream>

using namespace std;

class CPoint
{
public:
  CPoint()
   {

   }
};

CPoint pt;
void main()
{

} 

设置三个断点:CPoint构造函数处、pt全局对象定义处和 main函数定义处。选择调试运行 main函数,将会看到程序代码执行的先后顺序。

这时我们将发现findwm程序首先到达pt全局对象定义处;继续运行程序,程序到达CPoint类的构造函数;再继续运行程序,程序到达main函数处。

由此可见,无论是全局变量,还是全局对象,程序在运行时,在加载main函数之前,就已经为全局变量或全局对象分配了内存空间。

对一个全局对象来说,此时就会调用该对象的构造函数构造该对象,并进行初始化操作。

这解释了先前创建的Mfc程序的运行顺序为什么全局变量theApp的构造函数会在 WinMain 函数之前执行。

那么,为什么要定义一个全局对象theApp,让它在WinMain函数之前执行呢?该对象的作用是什么呢?我们回到Mfc项目,并将该项目设置为启动项目。

Win32 SDK应用程序的实例是由实例句柄(WinMain函数的参数hInstance)来标识的。而对MFC程序来说,通过产生一个应用程序类的对象来唯一标识应用程序的实例。每一个MFC程序有且仅有一个从应用程序类(CWinApp)派生的类。每一个MFC程序实例有且仅有一个该派生类的实例化对象,也就是theApp全局对象。该对象就表示了应用程序本身。

还记得子类构造函数的执行过程?当一个子类在构造之前会先调用其父类的构造函数。因此theApp对象的构造函数CMfcApp 在调用之前,会调用其父类CWinApp的构造函数,从而就把我们程序自己创建的类与Microsoft 提供的基类关联起来了。CWinApp的构造函数完成程序运行时的一些初始化工作。

下面让我们看看CWinApp类构造函数的定义。像前面搜索“WinMain”函数那样,找到Microsoft提供的CWinApp类定义的源文件:appcore.cpp,并在编辑环境中打开,其中CWinApp构造函数的代码如下。

CWinApp::CWinApp(LPCTSTR lpszAppName)
{
  if (lpszAppName != NULL)
     m_pszAppName=_tcsdup(lpszAppName);
  else
     m_pszAppName =NULL;
  
    // initialize CWinThread state
  AFX_MODULE_STATE* pModulestate =_AFX_CMDTARGET_GETSTATE();
  ENSURE (pModulestate);
   AFX_MODULE_THREAD_STATE* pThreadstate =pModulestate->m_thread;
  ENSURE(pThreadState);
  ASSERT(AfxGetThread()== NULL);
  pThreadstate->m_pCurrentwinThread=this;
  ASSERT (AfxGetThread() == this);
  m_hThread = ::GetCurrentThread();
  m_nThreadID=::GetCurrentThreadId();

  // initialize CWinApp state
  ASSERT(afxCurrentWinApp == NULL);
   pModuleState->m_pCurrentWinApp this;
  ASSERT (AfxGetApp ()== this);

  // in non-running state until WinMain
  m_hInstance= NULL;
  m_hLangResourceDLL= NULL;
  m_pszHelpFilePath= NULL;
  m_pszProfileName= NULL;
  m_pszRegistryKey= NULL;
  m_pszExeName= NULL;
  m_pszAppID= NULL;
  m_pRecentFileList= NULL;
  m_pDocManager= NULL;
  m_atomApp= m_atomSystemTopic= NULL;
  m_lpCmdLine= NULL;
  m_pCmdInfo= NULL;
  m_pDataRecoveryHandler= NULL;

  // initialize wait cursor state
  m_nWaitCursorCount =0;
  m_hcurWaitCursorRestore= NULL;

  // initialize current printer state
  m_hDevMode= NULL;
  m_hDevNames= NULL;
  m_nNumPreviewPages =0;

  // initialize DAO state
  m_lpfnDaoTerm= NULL;

  // other initialization
  m_bHelpMode= FALSE;
  m_eHelpType= afxwinHelp;
  m_nSafetyPoolsize= 512;
  m_dwRestartManagerSupportFlags =0;
  m_nAutosaveInterval = 5 * 60 * 1000;
   m_bTaskbarInteractionEnabled= TRUE;

  // Detect the kind of OS:
  OSVERSIONINFO osvi;
  osvi.dwosversionInfoSize= sizeof (OSVERSIONINFO);

  #pragma warning( disable 4996)
    ::GetVersionEx(&osvi);
  #pragma warning( default 4996)

  m_bIsWindows7 =(osvi. dwMajorVersion ==6) && (osvi. dwMinorVersion >=1)|| (osvi. dwMajorVersion >6);

  // Taskbar initialization:
  m_bComInitialized= FALSE;

  m_pTaskbarList= NULL;
  m_pTaskbarList3= NULL;
  m_bTaskBarInterfacesAvailable= TRUE;
}

上述CWinApp的构造函数中有这样两行代码:

pThreadState->m_pCurrentWinThread= this;

pModuleState->m_pCurrentWinApp= this;

m_pCurrentWinThread 对象的类型是 CWinThread,该类是 CWinApp 的父类。

根据C++继承性原理,这个this对象代表的是子类 CMfcApp的对象,即theApp。同时,可以发现CWinApp的构造函数有一个LPCTSTR类型的形参:lpszAppName。但是我们程序中CMfcApp的构造函数是没有参数的。如果基类的构造函数带有一个形参,那么子类构造函数需要显式地调用基类带参数的构造函数。那么,为什么我们程序中的 CMfcapp构造函数没有这么做呢?

如果某个函数的参数有默认值,那么在调用该函数时可以传递该参数的值,也可以不传递直接使用默认值即可。

class CWinApp : public CWinThread
{
  DECLARE DYNAMIC (CWinApp)

public:

  //Constructor

  explicit CWinApp(LPCTSTR lpszAppName=NULL);

  .....

可以看到,CWinApp构造函数的形参确实有一个默认值(NULL)。这样,在调用CWinApp类的构造函数时,就不用显式地去传递这个参数的值。

作者简介:荔园微风,1981年生,高级工程师,浙大工学硕士,软件工程项目主管,做过程序员、软件设计师、系统架构师,早期的Windows程序员,Visual Studio忠实用户,C/C++使用者,是一位在计算机界学习、拼搏、奋斗了25年的老将,经历了UNIX时代、桌面WIN32时代、Web应用时代、云计算时代、手机安卓时代、大数据时代、ICT时代、AI深度学习时代、智能机器时代,我不知道未来还会有什么时代,只记得这一路走来,充满着艰辛与收获,愿同大家一起走下去,充满希望的走下去。文章来源地址https://www.toymoban.com/news/detail-672548.html

到了这里,关于Visual Studio 2022的MFC框架——theApp全局对象的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Microsoft Visual Studio 2022添加.NET Framework 4.6.2框架,然后说下.NET目标包的作用。

    众所周知,Microsoft Visual Studio 2022不再支持.NET Framework 4.6以下的框架。从而导致前期使用老框架开发的某些应用无法打开(打开时提示安装框架,但又安装不成功)的情况出现。  前于如何安装.NET Framework 4.5及更早版本框架的方法,网上很多,甚至搜索4.6相关,出来的结

    2024年02月17日
    浏览(59)
  • 解决Unity游戏开发使用Visual Studio Enterprise 2022提示未找到目标框架.net framework4.7.1问题

    采用Visual Studio Installer安装Visual Studio Enterprise 2022,安装中勾选游戏下Unity游戏开发。 单个组件中确保勾选.NET Framework 4.7.1目标包 安装位置自定义修改至F盘后使用Visual Studio Enterprise 2022登录,在Unity设置使用Visual Studio Enterprise 2022并打开对应项目文件,提示未找到目标框架.net

    2024年02月10日
    浏览(60)
  • 【visual studio】visual studio 2022 无法 复制黏贴

    其他网友也有反馈到微软: VS 2022 Copy and Paste form feature Broken? Copy paste still not fixed in Visual studio 2022 表现是突然就无法复制和黏贴了 其他的app 就没有这个问题 每次都是重启电脑解决。 今天,11月29号是17.41版本了。 -net5.0直接卸载了

    2024年02月04日
    浏览(99)
  • visual studio 2022配置

    前提:我linux c 开发 一直在使用vscode 更新了个版本突然代码中的查找所用引用和变量修改名称不能用了,尝试了重新配置clang vc都不行,估计是插件问题,一怒之下改用visual studio 2022 为了同步2个IDE之间的差别,目前看着差不多,我在用用,有啥区别在进行修改 1、使用///添加

    2024年02月12日
    浏览(49)
  • Visual Studio下载(2022)

    1.搜索微软官网  2.点击微软官网,并点击右上角的 所有Microsoft    3.出现如上界面,点击开发人员中心    4.出现如上界面 ,往下滑动 5.点击Visual Studio  6,点击下载Visual Studio旁边的右下箭头。   7。点击Community2022(此为免费的社区版)   8.下载以后打开文件 9.点击继续 10,下

    2024年02月10日
    浏览(41)
  • Visual Studio 2022 更换主题

    🏆 个人愚见,没事写写笔记 🏆《博客内容》:Unity3D开发内容 🏆🎉欢迎 👍点赞✍评论⭐收藏 🔎目标:Visual Studio 2022想换个皮肤 ☀️实现目标: 准备工作:完成Visual Studio 2022 安装。 1.打开Visual Studio 2022第一步:  2.在弹出的浏览器中选择喜欢的主题下载:  3.找到下载好

    2024年02月12日
    浏览(49)
  • Visual Studio 2022 的下载

            子曰:“工欲善其事,必先利其器。”要做好一件事,准备工具非常重要。本文将带领 大家下载Microsoft Visual Studio Community 2022 。         1、到网上搜索Visual Studio 2022。网址: Visual Studio: IDE and Code Editor for Software Developers and Teams Visual Studio dev tools services make app deve

    2024年02月08日
    浏览(88)
  • 免费安装Visual Studio 2022

    我使用软件的选择顺序是优先选择开源软件,其次是社区免费版本,大部分时间我都是在linux下开发,很少在windows下写代码。但是在这microsoft还是处于统治地位的时代,而且很多新手写代码开始还是倾向于在windows下,因此推荐Visual Studio 2022 社区版,即满足我的个人选择倾向

    2024年02月11日
    浏览(56)
  • Unity + Visual Studio 2022

    安裝Visual Studio 2022的时候,需要勾选“使用Unity进行游戏开发”    Unity 中 Preference - External Tools - External Script Editor,要选择 Visual Studio 2022    开启后,使用VS开启Unity 项目后,我这里会提示“项目不相容”。检查是因为我之前使用Visual Studio 2017开启过这个项目,项目文件跟

    2024年02月12日
    浏览(50)
  • Microsoft Visual studio 2022 如何自定义背景(详细) Visual studio 2022 怎么改背景和幻灯片播放(自定义背景)

    1.新建一个项目,项目名称无所谓 进入编辑页面后,点击拓展管理拓展联机 右边搜索框搜索 ClaudiaIDE, 键入后点击回车搜索,然后点击下载,等待下载完成,(这里下载进度条一直不动的话可能是网络不好的原因,我这里已经安装好了) 下载完成后,关闭visual studio 2022,桌

    2024年02月06日
    浏览(91)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包