源码

 #include<afxwin.h>

 class MyApp :public CWinApp
{
public:
virtual BOOL InitInstance();
}; MyApp theApp; BOOL MyApp::InitInstance()
{
//创建一个代表框架窗口的类
CFrameWnd* pFrame = new CFrameWnd;
//在将框架窗口类和主程序类之间建立联系
this->m_pMainWnd = pFrame;
//创建窗口
pFrame->Create(NULL, TEXT("MFC"));//注册窗口类(::RegisterClassEx),创建窗口(::CreateWindowEx)
//显示窗口
pFrame->ShowWindow(SW_SHOW);//::ShowWindow
//刷新窗口
pFrame->UpdateWindow();//::UpdateWindow
return TRUE;
}

再第18行打一个断点。F5

调用顺序:

①kernel32.dll!

②wWinMainCRTStartup()

③__tmainCRTStartup()

④wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow)

⑤AfxWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow)

⑥MyApp::InitInstance()

对应Windows API编程,MFC把WinMain替换成了AfxWinMain,只是改了个函数名字,函数参数都一样。

AfxWinMain源码

 int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow)
{
ASSERT(hPrevInstance == NULL); int nReturnCode = -;
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, , "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 != )
{
TRACE(traceAppMsg, , "Warning: Temp map lock count non-zero (%ld).\n",
AfxGetModuleThreadState()->m_nTempMapLock);
}
AfxLockTempMaps();
AfxUnlockTempMaps(-);
#endif AfxWinTerm();
return nReturnCode;
}

CWinThread:代表一个线程

AfxGetThread():获得我们定义theApp对象的地址

AfxGetApp():获得我们定义theApp对象的地址

这两个函数都是获取我们定义theApp对象的地址:因为CMyApp继承与CWinApp,CWinApp继承于CWinThread。

消息循环在哪?

CWinApp::Run() ——>CWinThread::Run()——>CWinThread::PumpMessage() ——>AfxInternalPumpMessage()  ——>::TranslateMessage();和::DispatchMessage();

创建窗口

MyApp::InitInstance() ——>CFrameWnd::Create(const wchar_t * lpszClassName, const wchar_t * lpszWindowName, unsigned long dwStyle, const tagRECT & rect, CWnd * pParentWnd, const wchar_t * lpszMenuName, unsigned long dwExStyle, CCreateContext * pContext) ——>CWnd::CreateEx(unsigned long dwExStyle, const wchar_t * lpszClassName, const wchar_t * lpszWindowName, unsigned long dwStyle, int x, int y, int nWidth, int nHeight, HWND__ * hWndParent, HMENU__ * nIDorHMenu, void * lpParam)

注册窗口

CWinApp这个类(包括这个类的导出类)代表了我们的程序。一个程序,只允许有一个CWinApp或者继承自CWinApp类的对象实例。

CFrameWnd这个类,代表了程序框架窗口

CWinApp封装了消息循环

CFrameWnd封装了注册窗口类,创建窗口,显示和刷新窗口

通过这两个类,我们可以创建一个应用程序。这两个类将应用程序的窗口类注册,创建窗口,消息循环晚藏起来。

MFC编程——Where is WinMain?的更多相关文章

  1. VS2010/MFC编程入门之四(MFC应用程序框架分析)

    VS2010/MFC编程入门之四(MFC应用程序框架分析)-软件开发-鸡啄米 http://www.jizhuomi.com/software/145.html   上一讲鸡啄米讲的是VS2010应用 ...

  2. MFC编程 | tab control控件的使用

    因为课程需要,会用到MFC编程,所以讲一些经验总结下,以便日后使用查询. // tab control控件的使用 // 建立一个Cluster窗口,通过tab可以切换成C-Means和Fuzzy C- ...

  3. MFC编程 | 非模态对话框的定义

    因为课程需要,会用到MFC编程,所以讲一些经验总结下,以便日后使用查询. // 非模态对话框的定义 // 通过单文档菜单调用一个非模态窗口 1.首先在工程里插入一个对话框(如:IDD_DLG_TEST ...

  4. VS2010/MFC编程入门之五(MFC消息映射机制概述)

    VS2010/MFC编程入门之五(MFC消息映射机制概述)-软件开发-鸡啄米 http://www.jizhuomi.com/software/147.html 上一讲鸡啄米为大家简单分析了MFC应用 ...

  5. VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)

    VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)-软件开发-鸡啄米 http://www.jizhuomi.com/software/143.html   鸡啄米在上一讲中 ...

  6. VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)

    VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)-软件开发-鸡啄米 http://www.jizhuomi.com/software/141.html   上一讲中讲了VS20 ...

  7. VS2010/MFC编程入门之一(VS2010与MSDN安装过程图解)

    原文地址: VS2010/MFC编程入门之一(VS2010与MSDN安装过程图解)-软件开发-鸡啄米 http://www.jizhuomi.com/software/139.html   上一讲中鸡 ...

  8. VS2010/MFC编程入门教程之目录和总结

    鸡啄米的这套VS2010/MFC编程入门教程到此就全部完成了,虽然有些内容还未涉及到,但帮助大家进行VS2010/MFC的入门学习业已足够.以此教程的知识为基础,学习VS2010/MFC较为深入的内容 ...

  9. MFC编程汇总

    1.visual2017专业版MFC编程环境搭建及第一个MFC程序的创建 2.通过MFC设计一个简单的计价程序 3.控件——静态空间.编辑框控件.命令按钮.复选框和单选控件 4.控件添加——静态控件. ...

随机推荐

  1. centos7.5安装图形界面

    1.centos7.4安装图形界面 yum check-update && yum install epel-release && yum groupinstall & ...

  2. 【linux基础】Ubuntu下的终端多标签切换快捷键

    method: 方法一: alt+ alt+ alt+ 方法二: ctrl + pageUp ctrl + pageDown 方法三: Edit--> Keybord Shortcuts 到这里 ...

  3. Selenium ? 也要学...!

    一.selenium 简介 Selenium是ThroughtWorks公司一个强大的开源Web功能测试工具系列,包括Selenium-IDE.Selenium-RC.Selenium-Webdriv ...

  4. python 优雅的解析 jsonp

    一段 jsonp 格式数据 mtopjsonpweexcb1({"api":"mtop.taobao.idle.recycle.nextspunav.get", ...

  5. 【C/C++】缓冲区设计--环形队列

    原文链接:http://blog.csdn.net/billow_zhang/article/details/4420789 在程序的两个模块间进行通讯的时候,缓冲区成为一个经常使用的机制. 如上图, ...

  6. 最新 中钢网java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.中钢网等10家互联网公司的校招Offer,因为某些自身原因最终选择了中钢网.6.7月主要是做系统复习.项目复盘.LeetCo ...

  7. 一个后端开发者的前端语言基础:JavaScript

    JavaScript (一) 基本概述 (1) 概述 JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的 ...

  8. react生成二维码

    图片实例: 简介: QRCode.js 是一个生成二维码的JS库.主要是通过获取 DOM 的节点,再通过 HTML5 Canvas 绘制而成,不依赖任何库. 用法: 1. 在项目中引入qrcode.m ...

  9. JAVA_split 字符串按照 . 分割

    split 按照 . 分割字符串时 需要进行转义 代码: String[] str = obj_str.split("\\.") split 按照 \ 分割字符串时 需要多次转义 ...

  10. 【C++札记】new和delete

    介绍 1.malloc,free和new,delete区别. a.malloc,free是C/C++的标准库函数.new,delete是c++的操作符. b.malloc申请的是内存,严格意义不是&q ...