2023年7月17日发(作者:)
MFC的⼊⼝函数(main函数)其实想看MFC的main函数,打开任⼀⽤MFC开发的App,设⼀个断点,然后查看调⽤堆栈。拉到最底部(即最先开始调⽤的东西)在中可以看到如下代码:// This is a part of the Microsoft Foundation Classes C++ library.// Copyright (C) Microsoft Corporation// All rights reserved.//// This source code is only intended as a supplement to the// Microsoft Foundation Classes Reference and related// electronic documentation provided with the library.// See these sources for detailed information regarding the// Microsoft Foundation Classes product.#include "stdafx.h"#include "sal.h"/// export WinMain to force linkage to this moduleextern int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, int nCmdShow);extern "C" int WINAPI_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, int nCmdShow)#pragma warning(suppress: 4985){ // call shared/exported WinMain return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);}可以看到,转⼊了AfxWinMain,继续跟在中可以看到// This is a part of the Microsoft Foundation Classes C++ library.// Copyright (C) Microsoft Corporation// All rights reserved.//// This source code is only intended as a supplement to the// Microsoft Foundation Classes Reference and related// electronic documentation provided with the library.// See these sources for detailed information regarding the// Microsoft Foundation Classes product.#include "stdafx.h"#include "sal.h"/// Standard WinMain implementation// Can be replaced as long as 'AfxWinInit' is called firstint AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, int nCmdShow){ ASSERT(hPrevInstance == NULL); int nReturnCode = -1; CWinThread* pThread = AfxGetThread(); CWinApp* pApp = AfxGetApp(); 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) { TRACE(traceAppMsg, 0, "Warning: Destroying non-NULL m_pMainWndn"); pThread->m_pMainWnd->DestroyWindow(); } nReturnCode = pThread->ExitInstance(); goto InitFailure; } nReturnCode = pThread->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;}/可以看到,在这⾥⾯先对窗⼝进⾏了初始化,再对线程和app对象进⾏了初始化,即依次对三个函数的调⽤:AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow);pApp->InitApplication();pThread->InitInstance();⼀个个看:AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow):在中:// This is a part of the Microsoft Foundation Classes C++ library.// Copyright (C) Microsoft Corporation// All rights reserved.//// This source code is only intended as a supplement to the// Microsoft Foundation Classes Reference and related// electronic documentation provided with the library.// See these sources for detailed information regarding the// Microsoft Foundation Classes product.#include "stdafx.h"#ifdef _AFXDLL#include "afxglobals.h"#endif#include "sal.h"/BOOL AFXAPI AfxWinInit(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_z_ LPTSTR lpCmdLine, _In_ int nCmdShow){ ASSERT(hPrevInstance == NULL); // handle critical errors and avoid Windows message boxes SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); // set resource handles AFX_MODULE_STATE* pModuleState = AfxGetModuleState(); pModuleState->m_hCurrentInstanceHandle = hInstance; pModuleState->m_hCurrentResourceHandle = hInstance; // fill in the 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(); } // initialize thread specific data (for main thread) if (!afxContextIsDLL) AfxInitThread(); return TRUE;}pApp->InitApplication():在中:BOOL CWinApp::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;}pThread->InitInstance():在中:/// CWinThread default implementationBOOL CWinThread::InitInstance(){ ASSERT_VALID(this); return FALSE; // by default don't enter run loop}CWinThread::Run():// main running routine until thread exitsint CWinThread::Run(){ ASSERT_VALID(this); _AFX_THREAD_STATE* pState = AfxGetThreadState(); // for tracking the idle time state BOOL bIdle = TRUE; LONG lIdleCount = 0; // acquire and dispatch messages until a WM_QUIT message is received. for (;;) { // phase1: check to see if we can do idle work while (bIdle && !::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE)) { // call OnIdle while in bIdle state if (!OnIdle(lIdleCount++)) bIdle = FALSE; // assume "no idle" state } // phase2: pump messages while available do { // pump message, but quit on WM_QUIT if (!PumpMessage()) return ExitInstance(); // reset "no idle" state after pumping "normal" message //if (IsIdleMessage(&m_msgCur)) if (IsIdleMessage(&(pState->m_msgCur))) { bIdle = TRUE; lIdleCount = 0; } } while (::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE)); }}可以看到在CWinThread::Run()进⼊了消息循环,直到收到WM_QUIT消息,退出消息循环。最后看看AfxWinTerm():在中:void AFXAPI AfxWinTerm(void){
AfxUnregisterWndClasses(); // cleanup OLE if required CWinThread* pThread = AfxGetApp(); if (pThread != NULL && pThread->m_lpfnOleTermOrFreeLib != NULL) (*pThread->m_lpfnOleTermOrFreeLib)(TRUE, FALSE); // cleanup thread local tooltip window AFX_MODULE_THREAD_STATE* pModuleThreadState = AfxGetModuleThreadState(); if (pModuleThreadState->m_pToolTip != NULL) { if (pModuleThreadState->m_pToolTip->DestroyToolTipCtrl()) pModuleThreadState->m_pToolTip = NULL; } _AFX_THREAD_STATE* pThreadState = AfxGetThreadState(); if (!afxContextIsDLL) { // unhook windows hooks if (pThreadState->m_hHookOldMsgFilter != NULL) { ::UnhookWindowsHookEx(pThreadState->m_hHookOldMsgFilter); pThreadState->m_hHookOldMsgFilter = NULL; } if (pThreadState->m_hHookOldCbtFilter != NULL) { ::UnhookWindowsHookEx(pThreadState->m_hHookOldCbtFilter); pThreadState->m_hHookOldCbtFilter = NULL; } } // We used to suppress all exceptions here. But that's the wrong thing // to do. If this process crashes, we should allow Windows to crash // the process and invoke watson.}Remark:MFC的代码是可以⼀步步跟的,⼀步步看。⼤致的基础流程就是上述代码,这篇权当抛砖引⽟,需要深⼊学习MFC的框架还有很多要学习的。⼩菜鸟⼀枚,与⼤家共同学习。
发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1689605092a269941.html
评论列表(0条)