090918(星期五):MFC消息路由3, Frame8代码分析2

一、Frame8程序main函数第2-4

       pApp->InitApplication();

       pApp->InitInstance();

       pApp->Run();

 

这几个的函数的前提是:

CMyWinApp theApp; // global object

CWinApp* pApp = &theApp

 

1pApp->InitApplication();

这个函数在CMyWinApp这没有重新定义,继续看它的基类:

 

class CWinApp : public CWinThread

{

public:

       CWinApp* m_pCurrentWinApp;

       CWnd* m_pMainWnd;   //为什么要定义这个新的变量

 

public:

       CWinApp::CWinApp() {

              m_pCurrentWinApp = this;

       }

       CWinApp::~CWinApp() {

       }

 

       virtual BOOL InitApplication() {

              cout << "CWinApp::InitApplication /n";

              return TRUE;

       }

 

再看CWinApp的基类CWinThread

其中没有InitApplication函数的声名

InitApplication函数是从CWinApp起源的。

所以第二句pApp->InitApplication();执行的就是:

       virtual BOOL CWinApp ::InitApplication() {

              cout << "CWinApp::InitApplication /n";

              return TRUE;

       }

 

 

这里就有一个有意思的问题:

CMyWinApp theApp; // global object

CWinApp* pApp = &theApp

 

调用pApp->InitApplication()时,InitApplication是虚函数,首先看CMyWinApp中有没有实现,有重写的实现当然是调用之,现在是没有,所以去调用其基类的InitApplication,现在假设InitApplication函数是从CWinThread起源的虚函数,CWinThread:: InitApplication会被理会吗?修改代码试一下,结果是没有理会。

 

其实这个问题的实质是虚函数的管理机制,《深入浅出》也是有介绍的,可以抽时间看看。

 

2, 第三句pApp->InitInstance();

CMyWinApp中这个函数进行了重写。

class CMyWinApp : public CWinApp

{

public:

       CMyWinApp::CMyWinApp() {

       }

       CMyWinApp::~CMyWinApp() {

       }

       virtual BOOL InitInstance();

       DECLARE_MESSAGE_MAP()

};

毫无疑问,这次的执行就是它了:

BOOL CMyWinApp::InitInstance()

{

       cout << "CMyWinApp::InitInstance /n";

       m_pMainWnd = new CMyFrameWnd;

       return TRUE;

}

其中的m_pMainWndCWinApp的成员。这和真实的MFC应该差别不大。

这个new语句会调用CMyFrameWnd,其中有些打印语句用来表示真实情况下可能做了些什么。

CMyFrameWnd::CMyFrameWnd()

{

       Create(); // 这个函数是从CWnd起源的一个虚函数,被CFrameWnd重写

}

所以就执行下面的语句:

BOOL CFrameWnd::Create()

{

       cout << "CFrameWnd::Create /n";

       CreateEx();  // 这个函数不是虚函数,是CWnd的一个成员函数。

       return TRUE;

}

 

BOOL CWnd::CreateEx()

{

       cout << "CWnd::CreateEx /n";

       PreCreateWindow();

       return TRUE;

}

 

BOOL CWnd::PreCreateWindow()

{

       cout << "CWnd::PreCreateWindow /n";

       return TRUE;

}

综合起来,pApp->InitInstance();的输出就是:

cout << "CMyWinApp::InitInstance /n";

cout << "CFrameWnd::Create /n";

cout << "CWnd::CreateEx /n";

cout << "CWnd::PreCreateWindow /n";

 

这句话想告诉的是一个自定义的CMyWinApp实例初始化的过程(如果其中是使用Frame界面的话):

A, 先做CMyWinApp::InitInstance自己App实例的初始化

B, CMyFrameWnd在构造函数中进行一些初始化,Frame和界面相关的

C, 再调用CFrameWnd类(MFC提供)的Create

D,CWndCreateEx

E, CWndPreCreateWindow,后3条都是MFC写好的,虽然改动的可能性很小,但明白一下肯定很有意义。

 

3,第四句pApp->Run();

原型是CMyWinApp::Run RunCWinThread起源的一个虚函数。

CMyWinApp没有重写,但是其基类CWinApp是重写了这个Run函数的,所以继续调用

       virtual int Run() {

              cout << "CWinApp::Run /n";

              return CWinThread::Run();

       }

 

       virtual int CWinThread::Run() {

              cout << "CWinThread::Run /n";

              // AfxWndProc(...);    原本在这里开始消息循环了

              return 1;

       }

 

输出很明显了

cout << "CWinApp::Run /n";

cout << "CWinThread::Run /n";

 

表达的调用意义:

分别调用MFC提供的CWinAppCWinThreadRun函数。

 

明天继续Frame8的其他原理分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值