MFC框架程序剖析笔记(下篇)

本文探讨了MFC框架中AfxWinMain的实现,包括AfxGetThread和AfxGetApp的区别。文章指出,虽然在不同VC版本中AfxGetThread的行为有所变化,但其目的都是获取应用程序线程。InitInstance函数在窗口类注册、窗口创建等方面起到关键作用。作者还对窗口创建和注册的细节进行了猜想,并提到了CMainFrame对象在窗口创建过程中的作用。最后,讨论了窗口过程函数和消息处理机制的初步概念。
摘要由CSDN通过智能技术生成

4.探索AfxWinMain

在WinMain函数的定义中可以发现仅有一行:

return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

所以WinMain的具体实现是交给AfxWinMain完成的。

打开WinMain.cpp查看定义:

int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
      _In_ LPTSTR lpCmdLine, int nCmdShow)
{
      ASSERT(hPrevInstance == NULL);
 
      int nReturnCode = -1;
      CWinThread* pThread = AfxGetThread();           //CWinApp派生于CWinThread
      CWinApp* pApp = AfxGetApp();                    //CTestApp派生于CWinApp
 
      // AFX internal initialization
      if (!AfxWinInit(hInstance, hPrevInstance,lpCmdLine, nCmdShow))
             goto InitFailure;
 
      // App global initializations (rare)
      if (pApp != NULL &&!pApp->InitApplication())    //初始化应用程序,完成MFC内部初始化管理方面的工作
             goto InitFailure;
 
      // Perform specific initializations
      if (!pThread->InitInstance())                //初始化实例,完成注册窗口类、创建窗口、显示窗口、更新窗口等工作
      {
             if (pThread->m_pMainWnd != NULL)
             {
                   TRACE(traceAppMsg, 0,"Warning: Destroying non-NULL m_pMainWnd\n");
                   pThread->m_pMainWnd->DestroyWindow();
             }
             nReturnCode =pThread->ExitInstance();
             goto InitFailure;
      }
      nReturnCode = pThread->Run();           //run方法,与消息循环有关
 
InitFailure:
#ifdef _DEBUG
      // Check for missing AfxLockTempMap calls
      if(AfxGetModuleThreadState()->m_nTempMapLock != 0)
      {
             TRACE(traceAppMsg, 0,"Warning: Temp map lock count non-zero (%ld).\n",
                   AfxGetModuleThreadState()->m_nTempMapLock);
      }
      AfxLockTempMaps();
      AfxUnlockTempMaps(-1);
#endif
 
      AfxWinTerm();
      return nReturnCode;
}

关键行1:CWinThread* pThread =AfxGetThread();   

我们转到AfxGetThread函数的定义,位于THREDCORE.CPP文件中。

CWinThread* AFXAPI AfxGetThread()
{
      // check for current thread in modulethread state
      AFX_MODULE_THREAD_STATE* pState =AfxGetModuleThreadState();
      CWinThread* pThread =pState->m_pCurrentWinThread;
      return pThread;
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------

发现与书中相比少了如下几行:

//if no CWinThreadfor the module, then use the global app.
     if(pThread == NULL)
            pThread = AfxGetApp();

 

根据MSDN2013对于AfxGetThread的批注:

    If you are porting an MFC project calling AfxGetThread fromVisual C++ versions 4.2, 5.0, or 6.0,AfxGetThread calls AfxGetApp if no thread is found. In VisualC+ .NET and later,AfxGetThread returnsNULL if nothread was found. If you want the application thread, you must call AfxGetApp.

    翻译:

    如果你正在移植一个MFC项目,并且是从旧版本的VC++(如VC++6.0调用AfxGetThread函数,那么AfxGetThread调用AfxGetApp如果没有找到线程。(如上面的代码:pThread=AfxGetApp(); )在之后的VC版本中,如果没有找到线程,那么这个函数返回值是NULL。如果你想要获得应用程序线程,必须调用AfxGetApp。

-------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

关键行2:CWinAPP* pApp =AfxGetApp ();

查看AfxGetApp定义:位于AFXWIN1.INL

_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp()
      { return afxCurrentWinApp; }

 

查看afxCurrentWinApp的定义:位于AFXWIN.H

#define afxCurrentWinApp   AfxGetModuleState()->m_pCurrentWinApp

     根据前面CWinApp构造函数的定义,m_pCurrentWinApp存放的就是theApp对象。

     也就是说,对于Test程序,pApp指向的是theApp这个全局对象。

     但是调用了AfxGetApp函数也没有明白pThread指针指向哪里,书中是在pThread为NULL时让pThread = AfxGetApp();,而现在没有这行赋值语句?

     这里我的猜想是pThread会在调用其他函数的时候来得到应用程序线程(Test应用程序只有一个线程,多线程的问题以后再研究),因为pThread->InitInstance(),pThread->ExitIn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值