091011(星期天)MFC的程序入口

来源:互联网 发布:网络视听经营许可证 编辑:程序博客网 时间:2024/05/17 22:16

 

使用MFC编程的程序员刚开始都会提出这样一个问题:我的程序是从哪儿开始执行的?回答是: WinMain()开始执行的。提出这样的问题是由于在他们所编写的MFC应用中看不到WinMain()函数。这个函数是隐藏在MFC框架中,MFC 的设计者将它作得很通用(这主要得益于Window的消息驱动的编程机制,使得作一个通用的WinMain()很容易),因此在一般情况下,无需更改 WinMain()的代码,MFC的设计者也不提倡程序员修改WinMain()的代码。在MFC,实际实现WinMain()的代码是 AfxWinMain()函数(根据其前缀Afx就知道这是一个全局的MFC函数)。

 

  一个Win32应用程序(或进程)是由一个或多 个并发的线程组成的,其中第一个启动的线程称为主线程,在Window下,一般将线程分成两大类,界面线程和工作线程,工作线程就是一般的线程,它没有窗 口,没有消息队列等,界面线程拥有一个或多个窗口,拥有一个消息队列和其他专属于界面线程的元素。在讨论AfxWinMain()之前,首先要简略提一下 MFC中的两个重要的类,CWinThreadCWinAppCWinThread是用来封装界面线程的类,CWinApp是从CWinThread 派生而来的。在CWinThread中,有两个很重要的虚拟函数InitInstance()和ExitInistance(),MFC的程序员应该对这 两个函数应该很熟悉。在CWinApp中,增加了另外一个虚拟函数InitApplication(),讨论AfxWinMain()的主要目的是看这些 函数是如何被调用的。

  AfxWinMain()的代码如下:

int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

       LPTSTR lpCmdLine, int nCmdShow)

{

       ASSERT(hPrevInstance == NULL);

 

       int nReturnCode = -1;

       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)

              {

                     TRACE0("Warning: Destroying non-NULL m_pMainWnd/n");

                     pThread->m_pMainWnd->DestroyWindow();

              }

              nReturnCode = pThread->ExitInstance();

              goto InitFailure;

       }

       nReturnCode = pThread->Run();

 

InitFailure:

       AfxWinTerm();

       return nReturnCode;

}

   在上面的代码中,AfxGetThread()返回的是当前界面线程对象的指针,AfxGetApp()返回的是应用程序对象的指针,如果该应用程序 (或进程)只有一个界面线程在运行,那么这两者返回的都是一个全局的应用程序对象指针,这个全局的应用程序对象就是MFC应用框架所默认的theApp 象(每次使用AppWizard生成一个SDIMDI应用程序时,AppWizard都会添加CYourApp theApp这条语句,AfxGetApp()返回的就是这个theApp的地址)。

 

CWinApp::InitApplication(), CWinThread::InitInstance(), CWinThread::ExitInstance()的调用情况。

CWinThread::PumpMessage() line 848 + 30 bytes

 

CWnd::RunModalLoop(unsigned long 4) line 3489 + 19 bytes

 

CDialog::DoModal() line 539 + 12 bytes

 

CIntelligentFtpApp::InitInstance() line 65 + 11 bytes

 

AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00151f26, int 1) line 39 + 11 bytes

 

WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00151f26, int 1) line 30

 

WinMainCRTStartup() line 198 + 54 bytes

 

KERNEL32! 7c816fd7()

 

原创粉丝点击