16,471
社区成员
发帖
与我相关
我的任务
分享
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 (;;)
{
/**当处于bIdle为真,且消息队列中取不到消息时,执行空闲操作*/
while (bIdle &&
!::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE))
{
if (!OnIdle(lIdleCount++))
bIdle = FALSE;
}
// 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));
}
}
BOOL CWinApp::OnIdle(LONG lCount)
{
if (lCount <= 0)
{
CWinThread::OnIdle(lCount);
// call doc-template idle hook
POSITION pos = NULL;
if (m_pDocManager != NULL)
pos = m_pDocManager->GetFirstDocTemplatePosition();
while (pos != NULL)
{
CDocTemplate* pTemplate = m_pDocManager->GetNextDocTemplate(pos);
ASSERT_KINDOF(CDocTemplate, pTemplate);
// if auto-save is enabled, the auto-save will be performed in the
// document's OnIdle method, called from the template's OnIdle method
pTemplate->OnIdle();
}
CDataRecoveryHandler *pHandler = GetDataRecoveryHandler();
if (pHandler)
{
// clear the auto-save on idle flag--it will be set
// again the next time the auto-save timer ticks.
pHandler->SetSaveDocumentInfoOnIdle(FALSE);
}
}
else if (lCount == 1)
{
VERIFY(!CWinThread::OnIdle(lCount));
}
return lCount < 1; // more to do if lCount < 1
}
BOOL CWinThread::OnIdle(LONG lCount)
{
ASSERT_VALID(this);
/*当ICount <= 0时,通过向窗口发送WM_IDLEUPDATECMDUI消息
去更新菜单,工具栏等*/
if (lCount <= 0)
{
// send WM_IDLEUPDATECMDUI to the main window
CWnd* pMainWnd = m_pMainWnd;
if (pMainWnd != NULL && pMainWnd->m_hWnd != NULL &&
pMainWnd->IsWindowVisible())
{
AfxCallWndProc(pMainWnd, pMainWnd->m_hWnd,
WM_IDLEUPDATECMDUI, (WPARAM)TRUE, 0);
pMainWnd->SendMessageToDescendants(WM_IDLEUPDATECMDUI,
(WPARAM)TRUE, 0, TRUE, TRUE);
}
// send WM_IDLEUPDATECMDUI to all frame windows
AFX_MODULE_THREAD_STATE* pState = _AFX_CMDTARGET_GETSTATE()->m_thread;
CFrameWnd* pFrameWnd = pState->m_frameList;
while (pFrameWnd != NULL)
{
if (pFrameWnd->m_hWnd != NULL && pFrameWnd != pMainWnd)
{
if (pFrameWnd->m_nShowDelay == SW_HIDE)
pFrameWnd->ShowWindow(pFrameWnd->m_nShowDelay);
if (pFrameWnd->IsWindowVisible() ||
pFrameWnd->m_nShowDelay >= 0)
{
AfxCallWndProc(pFrameWnd, pFrameWnd->m_hWnd,
WM_IDLEUPDATECMDUI, (WPARAM)TRUE, 0);
pFrameWnd->SendMessageToDescendants(WM_IDLEUPDATECMDUI,
(WPARAM)TRUE, 0, TRUE, TRUE);
}
if (pFrameWnd->m_nShowDelay > SW_HIDE)
pFrameWnd->ShowWindow(pFrameWnd->m_nShowDelay);
pFrameWnd->m_nShowDelay = -1;
}
pFrameWnd = pFrameWnd->m_pNextFrameWnd;
}
}
/*当ICount >= 0时,则去清理一些临时对象,通常是FromHandle等函数产生的*/
else if (lCount >= 0)
{
AFX_MODULE_THREAD_STATE* pState = _AFX_CMDTARGET_GETSTATE()->m_thread;
if (pState->m_nTempMapLock == 0)
{
// free temp maps, OLE DLLs, etc.
AfxLockTempMaps();
AfxUnlockTempMaps();
}
}
return lCount < 1; // nothing more to do if lCount >= 1
}