MFCのエントリ関数(main関数)
8200 ワード
実はMFCのmain関数を見て、MFCで開発したAppを開いて、ブレークポイントを設定して、呼び出しスタックを見たいです.一番下に引く(つまり最初に呼び出したもの)
appmodulでcppには、次のコードが表示されます.
AfxWinMainに移行し、
winmainでcppでは
ここでウィンドウを初期化し、スレッドとappオブジェクトを初期化します.すなわち、3つの関数の呼び出しが順次行われます.
AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
pApp->InitApplication();
pThread->InitInstance();
一つ一つ見る:
AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow):
appinit.cpp:
pApp->InitApplication():
appcore.cpp:
pThread->InitInstance():
thrdcore.cpp:
CWinThread::Run():
CWinThread::Run()がWM_を受信するまでメッセージループに入っていることがわかりますQUITメッセージ、メッセージループを終了します.
最後にAfxWinTerm()を見てみましょう.
appterm.cpp:
Remark:
MFCのコードは一歩一歩ついていくことができて、一歩一歩見ます.
大まかな基礎の流れは上述のコードで、この権はレンガを投げて玉を引くと、MFCの枠組みを深く学ぶ必要があります.
おかず鳥一枚、みんなと一緒に勉強します.
appmodulでcppには、次のコードが表示されます.
// 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 module
extern 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に移行し、
winmainでcppでは
// 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 first
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ 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)
{
TRACE(traceAppMsg, 0, "Warning: Destroying non-NULL m_pMainWnd
");
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).
",
AfxGetModuleThreadState()->m_nTempMapLock);
}
AfxLockTempMaps();
AfxUnlockTempMaps(-1);
#endif
AfxWinTerm();
return nReturnCode;
}
/////////////////////////////////////////////////////////////////////////////
ここでウィンドウを初期化し、スレッドとappオブジェクトを初期化します.すなわち、3つの関数の呼び出しが順次行われます.
AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
pApp->InitApplication();
pThread->InitInstance();
一つ一つ見る:
AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow):
appinit.cpp:
// 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():
appcore.cpp:
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():
thrdcore.cpp:
/////////////////////////////////////////////////////////////////////////////
// CWinThread default implementation
BOOL CWinThread::InitInstance()
{
ASSERT_VALID(this);
return FALSE; // by default don't enter run loop
}
CWinThread::Run():
// main running routine until thread exits
int 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()を見てみましょう.
appterm.cpp:
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の枠組みを深く学ぶ必要があります.
おかず鳥一枚、みんなと一緒に勉強します.