(1)编译器首先替你初始化没有初始化全局变量。编译器根据编译选项指定整个程序的入口函数,在unicode和windows(非console)的情况下,为wWinMainCRTStartup(wWinMain)
(2)然后在入口函数中,编译器写代码(实际上是已有代码根据然后链接进来)调用全局对象的构造函数,对全局对象进行初始化,所以你的构造函数会在main函数调用之前被调用。最重要的全局对象就是Application object对象theApp,全局有且只有1个。
(3)实际执行中,当执行万上述步骤,就执行winmain,注意,该函数隐藏在MFC库中,也由链接器负责直接加入
(4)下面我们可以看见winmain干了什么,其实他就调用了afxwinmain
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
// call shared/exported WinMain
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
(5)下面我们看这个afxwinmain做了些什么
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
int nReturnCode = -1;
CWinApp* pApp = AfxGetApp();
AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
pApp->InitApplication();
pApp->InitInstance()
nReturnCode = pApp->Run();
AfxWinTerm();
return nReturnCode;
}
注意,afxgetapp获得的是你的app类对象的指针(也就是那个唯一的Application object)。这个类一定是继承自cwinapp。然后它调用了自己的
InitApplication(),<pre name="code" class="cpp">InitInstance()
Run()
三个方法,如果你没有改写这三个方法的话,这三个方法就是cwinapp的同名三个方法。(分别为(6)(7)(8)部叙述)
(6)前两个方法AfxWinInit和initapplication对应着一些初始化操作,后者虽然是由你的app类调用的,但是一般不被改写,目前没看懂
(7)initinstance会被改写,也就会出现在XXXapp.cpp文件中。典型如下,根据你在想到中的选择,IDE会自动帮你生成代码(下图为主干内容),一般而言,这里会有些例如公共控件,COM,OLE,active X控件)的初始化内容.(关于他们三个的关系,可以参考http://blog.sina.com.cn/s/blog_557ee0540100cukp.html)
BOOL CtestMFCIcon2App::InitInstance()
{
CWinApp::InitInstance();
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));//处理注册表
CtestMFCIcon2Dlg dlg;//生成主题对话框并调整其模态
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
return FALSE;
}
如果不是一个对话框而是一个单文档窗口,则主干代码如下:
BOOL CmyWinTestApp::InitInstance()
{
CWinApp::InitInstance();
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
// 若要创建主窗口,此代码将创建新的框架窗口
// 对象,然后将其设置为应用程序的主窗口对象
CMainFrame* pFrame = new CMainFrame;
if (!pFrame)
return FALSE;
m_pMainWnd = pFrame;
// 创建并加载框架及其资源
pFrame->LoadFrame(IDR_MAINFRAME,
WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,
NULL);
// 唯一的一个窗口已初始化,因此显示它并对其进行更新
pFrame->ShowWindow(SW_SHOW);
pFrame->UpdateWindow();
return TRUE;
}
创建主窗口(其实子窗口过程中),会调用PreCreateWindow决定窗口的具体参数
(8)run函数一般也不会被改写,是开启消息循环。这里的重点是message map机制。有一些代码IDE会自动帮你产生,例如:
class CMyFrameWnd : public CFrameWnd
{
public:
CMyFrameWnd();
afx_msg void OnPaint(); // for WM_PAINT
afx_msg void OnAbout(); // for WM_COMMAND (IDM_ABOUT)
DECLARE_MESSAGE_MAP()
}
在框架类中的各种函数处理,还有(以下代码可以写在框架cpp文件的任何部分,只要不是在函数中)
BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
ON_COMMAND(IDM_ABOUT, OnAbout)
ON_WM_PAINT()
END_MESSAGE_MAP()
本文主要参考自http://www.cnblogs.com/lidabo/archive/2012/10/23/2735622.html Double Li的博客,在此向原作者表示感谢。