MFC 流程跟踪(窗口设计,注册,创建)

本文详细剖析了MFC应用程序的流程,从_tWinMain函数开始,逐步深入到AfxWinInit、CWinApp::InitApplication、CWinApp::ProcessShellCommand等关键步骤,揭示了窗口设计、注册和创建的具体过程。文章通过代码分析,展示了如何在MFC中进行窗口类的设计、注册及窗口实例的创建,包括AfxDeferRegisterClass、AfxEndDeferRegisterClass、AfxRegisterClass等函数的作用。
摘要由CSDN通过智能技术生成

MFC的流程跟踪

(窗口的设计,注册,创建)

跟踪MFC的程序流程,我们一步一步来,不要怕麻烦!

1       首先是MFC的入口函数:

extern "C"int WINAPI

_tWinMain(HINSTANCEhInstance, HINSTANCE hPrevInstance,

         _In_ LPTSTR lpCmdLine, int nCmdShow)

#pragma warning(suppress:4985)

{

         // callshared/exported WinMain

         returnAfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

}

2       然后进入AfxWinMain(hInstance, hPrevInstance, lpCmdLine,nCmdShow);

int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCEhPrevInstance,

         _In_ LPTSTR lpCmdLine, int nCmdShow)

{

         ASSERT(hPrevInstance == NULL);

        

         // pThreadpApp都是指向the App全局对象,不过这两个指针都是the App的父类指针

         intnReturnCode = -1;

         CWinThread* pThread = AfxGetThread();

         CWinApp* pApp = AfxGetApp();

 

         // 这个是完成MFC的初始化

         if(!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))

                   gotoInitFailure;

 

         // 应用程序全局初始化,主要是文档相关

         if(pApp != NULL && !pApp->InitApplication())

                   gotoInitFailure;

 

         // 调用子类的Instance函数来实现初始化,这个是重点,窗口的设计

         // 注册,创建都在这个函数里面了,中间会调用很多函数

         if(!pThread->InitInstance())

         {

                   if(pThread->m_pMainWnd != NULL)

                   {

                            TRACE(traceAppMsg,0, "Warning: Destroying non-NULLm_pMainWnd\n");

                            pThread->m_pMainWnd->DestroyWindow();

                   }

                   nReturnCode =pThread->ExitInstance();

                   gotoInitFailure;

         }

         // 消息循环

         nReturnCode = pThread->Run();

 

InitFailure:

#ifdef _DEBUG

         // Check formissing 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();

         returnnReturnCode;

}

 

2.1 接下来进入AfxWinInit看看

BOOL AFXAPIAfxWinInit(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,

         _In_z_ LPTSTR lpCmdLine, _In_ int nCmdShow)

{

         ASSERT(hPrevInstance == NULL);

 

 

         // handlecritical errors and avoid Windows message boxes

         SetErrorMode(SetErrorMode(0) |

                   SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);

 

         // setresource handles

         AFX_MODULE_STATE* pModuleState =AfxGetModuleState();

         pModuleState->m_hCurrentInstanceHandle= hInstance;

         pModuleState->m_hCurrentResourceHandle= hInstance;

         pModuleState->CreateActivationContext();

 

         // fill inthe initial state for the application

         CWinApp* pApp = AfxGetApp();

         if(pApp != NULL)

         {

                   //Windows specific initialization (not done if no CWinApp)

                   pApp->m_hInstance =hInstance;

                   hPrevInstance; // Obsolete.

                   pApp->m_lpCmdLine =lpCmdLine;

                   pApp->m_nCmdShow =nCmdShow;

                   pApp->SetCurrentHandles();

         }

 

         // initializethread specific data (for main thread)

         if(!afxContextIsDLL)

                   AfxInitThread();

 

         returnTRUE;

}

 

这个函数主要就是完成MFC的初始化,也不需要多解释。其实如果我在控制台程序创建时,勾选了MFC的库,那么在_tmain函数中也会出现这样一个东西,如下:

int _tmain(int argc,TCHAR* argv[], TCHAR* envp[])

{

         int nRetCode = 0;

 

         HMODULE hModule =::GetModuleHandle(NULL);

 

         if (hModule != NULL)

         {

                   // 初始化 MFC 并在失败时显示错误

                   if (!AfxWinInit(hModule,NULL, ::GetCommandLine(), 0))

                   {

                            // TODO: 更改错误代码以符合您的需要

                            _tprintf(_T("错误: MFC 初始化失败\n"));

                            nRetCode = 1;

                   }

                   else

                   {

                            // TODO: 在此处为应用程序的行为编写代码。

                   }

         }

         else

         {

                   // TODO: 更改错误代码以符合您的需要

                   _tprintf(_T("错误: GetModuleHandle 失败\n"));

                   nRetCode = 1;

         }

 

         return nRetCode;

}

2.2    再看看BOOLCWinApp::InitApplication()

BOOLCWinApp::InitApplication()

{

         if (CDocManager::pStaticDocManager !=NULL)

         {

                   if (m_pDocManager == NULL)

                            m_pDocManager =CDocManager::pStaticDocManager;

                   CDocManager::pStaticDocManager= NULL;

         }

 

         if (m_pDocManager != NULL)

                   m_pDocManager->AddDocTemplate(NULL);

         else

                   CDocManager::bStaticInit =FALSE;

 

         LoadSysPolicies();

 

         return TRUE;

}

这个函数主要就是管理文档的,对目前跟踪流程也没多大用处,先不管它

2.3    接下来再进入我们最关心的函数Instance看看,就是在这个函数中我们进行了窗口的设计,注册,创建,让我们一步一步地揭开它神秘的面纱吧。

BOOL Cmfc4StdApp::InitInstance()

{

         InitCtrls.dwSize = sizeof(InitCtrls);

         InitCtrls.dwICC = ICC_WIN95_CLASSES;

         InitCommonControlsEx(&InitCtrls);

         CWinAppEx::InitInstance();

 

         if(!AfxOleInit())

         {

                   AfxMessageBox(IDP_OLE_INIT_FAILED);

                   returnFALSE;

         }

 

         AfxEnableControlContainer();

         EnableTaskbarInteraction(FALSE);

         SetRegistryKey(_T(应用程序向导生成的本地应用程序));

         LoadStdProfileSettings(4);  // 加载标准的INI文件

 

         InitContextMenuManager();

 

         InitKeyboardManager();

 

         InitTooltipManager();

         CMFCToolTipInfo ttParams;

         ttParams.m_bVislManagerTheme = TRUE;

         theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,

                   RUNTIME_CLASS(CMFCToolTipCtrl),&ttParams);

 

         // 注册应用程序的文档模板,文档模板将用作文档,框架,视口之间的连接

         CSingleDocTemplate* pDocTemplate;

         pDocTemplate = newCSingleDocTemplate(

                   IDR_MAINFRAME,

                   RUNTIME_CLASS(Cmfc4StdDoc),

                   RUNTIME_CLASS(CMainFrame),       // SDI框架

                   RUNTIME_CLASS(Cmfc4StdView));

         if(!pDocTemplate)

                   returnFALSE;

         AddDocTemplate(

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值