MFC 程序来龙去脉_子文档 5
MFC 程序来龙去脉_子文档 5
探究 nReturnCode = pThread->Run()
查看 pThread->Run 代码(C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\src\mfc\thrdcore.cpp):
int CWinApp::Run()
{
if (m_pMainWnd == NULL && AfxOleGetUserCtrl())
{
// Not launched /Embedding or /Automation, but has no main window!
TRACE(traceAppMsg, 0, "Warning: m_pMainWnd is NULL in CWinApp::Run - quitting application.\n");
AfxPostQuitMessage(0);
}
return CWinThread::Run();
}
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));
}
}
想了解 PeekMessage 更多请看:深入GetMessage和PeekMessage
现在,我们只需要知道PeekMessage截取走了一些消息,主要的消息处理还是靠 PumpMessage 来处理,查看 PumpMessage 源码:
BOOL CWinThread::PumpMessage()
{
return AfxInternalPumpMessage();
}
查看 AfxInternalPumpMessage 源码:
BOOL AFXAPI AfxInternalPumpMessage()
{
_AFX_THREAD_STATE *pState = AfxGetThreadState();
if (!::GetMessage(&(pState->m_msgCur), NULL, NULL, NULL))
{
#ifdef _DEBUG
TRACE(traceAppMsg, 1, "CWinThread::PumpMessage - Received WM_QUIT.\n");
pState->m_nDisablePumpCount++; // application must die
#endif
// Note: prevents calling message loop things in 'ExitInstance'
// will never be decremented
return FALSE;
}
#ifdef _DEBUG
if (pState->m_nDisablePumpCount != 0)
{
TRACE(traceAppMsg, 0, "Error: CWinThread::PumpMessage called when not permitted.\n");
ASSERT(FALSE);
}
#endif
#ifdef _DEBUG
_AfxTraceMsg(_T("PumpMessage"), &(pState->m_msgCur));
#endif
// process this message
if (pState->m_msgCur.message != WM_KICKIDLE && !AfxPreTranslateMessage(&(pState->m_msgCur)))
{
::TranslateMessage(&(pState->m_msgCur));
::DispatchMessage(&(pState->m_msgCur));
}
return TRUE;
}
我们看到了Win32 App中熟悉的 DispatchMessage 和 DispatchMessage 方法。