目录
CWinThread类的Run函数(thrdcore.cpp):
AfxInternalPumpMessage函数(thrdcore.cpp):
接上:VC++MFC框架窗口(三)CreateEx 函数 Create函数 下载PDB文件
至此,注册窗口类、创建窗口、显示和更新窗口的工作都已完成,就该进入消息循环了。CWinThread类的Run函数就是完成消息循环这一任务的,该函数是在AfxWinMain函数中调用的,调用形式如下(位于 AfxWinMain函数实现代码处)所示。
thrdcore.cpp:
nResult = pThread->Run();
AfxWinMain函数(winmain.cpp):
连接:VC++MFC程序中的WinMain函数(四) AfxWinMain函数 AfxGetThread函数 AfxGetApp函数 afxCurrentWinApp函数
nReturnCode = pThread->Run();
CWinThread类的Run函数(thrdcore.cpp):
// 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));
}
}
该函数的主要结构是一个for循环,该循环在接收到一个WM_QUIT消息时退出。在此循环中调用了一个PumpMessage函数,使用【转到定义】功能找到该函数的实现代码,如下所示。
if (!PumpMessage())
PumpMessage函数(thrdcore.cpp):
BOOL CWinThread::PumpMessage()
{
return AfxInternalPumpMessage();
}
继续使用【转到定义】功能找到AfxInternalPumpMessage函数的实现代码,如下所示。
AfxInternalPumpMessage函数(thrdcore.cpp):
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;
}
可以发现,这与前面讲述的SDK编程(WinMain程序)的消息处理代码是一致的。