MFC执行顺序

(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的博客,在此向原作者表示感谢。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值