MFC编程——Where is WinMain?
源码
#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?的更多相关文章
- VS2010/MFC编程入门之四(MFC应用程序框架分析)
VS2010/MFC编程入门之四(MFC应用程序框架分析)-软件开发-鸡啄米 http://www.jizhuomi.com/software/145.html 上一讲鸡啄米讲的是VS2010应用 ...
- MFC编程 | tab control控件的使用
因为课程需要,会用到MFC编程,所以讲一些经验总结下,以便日后使用查询. // tab control控件的使用 // 建立一个Cluster窗口,通过tab可以切换成C-Means和Fuzzy C- ...
- MFC编程 | 非模态对话框的定义
因为课程需要,会用到MFC编程,所以讲一些经验总结下,以便日后使用查询. // 非模态对话框的定义 // 通过单文档菜单调用一个非模态窗口 1.首先在工程里插入一个对话框(如:IDD_DLG_TEST ...
- VS2010/MFC编程入门之五(MFC消息映射机制概述)
VS2010/MFC编程入门之五(MFC消息映射机制概述)-软件开发-鸡啄米 http://www.jizhuomi.com/software/147.html 上一讲鸡啄米为大家简单分析了MFC应用 ...
- VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)
VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)-软件开发-鸡啄米 http://www.jizhuomi.com/software/143.html 鸡啄米在上一讲中 ...
- VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)
VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)-软件开发-鸡啄米 http://www.jizhuomi.com/software/141.html 上一讲中讲了VS20 ...
- VS2010/MFC编程入门之一(VS2010与MSDN安装过程图解)
原文地址: VS2010/MFC编程入门之一(VS2010与MSDN安装过程图解)-软件开发-鸡啄米 http://www.jizhuomi.com/software/139.html 上一讲中鸡 ...
- VS2010/MFC编程入门教程之目录和总结
鸡啄米的这套VS2010/MFC编程入门教程到此就全部完成了,虽然有些内容还未涉及到,但帮助大家进行VS2010/MFC的入门学习业已足够.以此教程的知识为基础,学习VS2010/MFC较为深入的内容 ...
- MFC编程汇总
1.visual2017专业版MFC编程环境搭建及第一个MFC程序的创建 2.通过MFC设计一个简单的计价程序 3.控件——静态空间.编辑框控件.命令按钮.复选框和单选控件 4.控件添加——静态控件. ...
随机推荐
- 基于Spark的用户分析系统
https://blog.csdn.net/ytbigdata/article/details/47154529
- Redis高级功能 - 慢查询日志
转自 https://segmentfault.com/a/1190000009915519
- 【Leetcode_easy】1122. Relative Sort Array
problem 1122. Relative Sort Array 参考 1. Leetcode_easy_1122. Relative Sort Array; 2. helloacm; 完
- Zuul1与Spring Cloud Gateway对比
一.API网关 1.1 Zuul1简介 1.2 Spring Cloud Gateway简介 二.对比 2.0 产品对比 2.1 性能对比 2.1.1 低并发场景 2.1.2 高并发场景 2.1.3 ...
- utf8 unicode 编码互转
static function utf8_to_unicode($c) { switch(strlen($c)) { case 1: return ord($c); case 2: $n = (ord ...
- 综合练习2 设置访问权限,Easy-IP访问外网,内外网访问
实验拓扑图: 实验要求: 1.pc.路由.交换基本配置,vlan间路由互通. 2.vlan20.vlan30可以访问FTP,VLAN10不允许访问FTP. 3.AR1通过easy-ip方式实现私网地址 ...
- Asp.Net Core中的角色
在前面介绍中我们知道了Asp.Net Core Identity中创建用户使用到的类UserManager<IdentityUser>,同样的,创建角色我们需要使用RoleManager& ...
- jquery入口函数的测试
/*编写一个自定义的jquery框架*/ (function (window,undefined) { var njquery=function (selector ,) { return new j ...
- if("\v"=="v")来判断IE浏览器
if(!+"\v1"){ IE代码}else{ 其他浏览器代码} if("\v"=="v"){//true为IE浏览器, document. ...
- java. util. concurrent. atomic
一.原子更新基本类型 AtomicInteger AtomicBoolean AtomicLong 二.原子更新数组 AtomicIntegerArray AtomicLongArray Atomic ...