看CWnd级代码:(程序一直在这个循环工作)
int CWnd::RunModalLoop(DWORD dwFlags)
{
for (;;)
{
// phase1: 处理空闲work
while (bIdle &&
!::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
{
// code...,这里有一处可以让循环退出的bool变量.
}
// phase2: 取出messages 当可用的时候,最后程序一直在这个循环工作
do
{
// pump message, but quit on WM_QUIT
// 这里PumpMessage()函数将CWinThread级的自己的PreTranslateMessage函数
if (!AfxGetThread()->PumpMessage()) // CWinThread级的代码
{
AfxPostQuitMessage(0);
return -1;
}
}
}while (::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE));
}
在看CWinThread级的代码:
BOOL CWinThread::PumpMessage()
{
if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))
{
}
// process this message, CWinThread级的自己的PreTranslateMessage函数开始调用
if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur))
{
::TranslateMessage(&m_msgCur);
::DispatchMessage(&m_msgCur);
}
}
// CWinThread级的PreTranslateMessage函数开始调用
BOOL CWinThread::PreTranslateMessage(MSG* pMsg)
{
CWnd* pMainWnd = AfxGetMainWnd();
// 注意WalkPreTranslateTree这个函数,这个函数会根据MSG的参数得到该消息窗口句柄,
if (CWnd::WalkPreTranslateTree(pMainWnd->GetSafeHwnd(), pMsg))
return TRUE;
// other code
CWnd* pMainWnd = AfxGetMainWnd();
return pMainWnd->PreTranslateMessage(pMsg); //
}
// 这个函数大概就是关键,也就是说虽然有MessageBox对话框弹出,但是不妨碍消息发送到其他窗口啊
BOOL PASCAL CWnd::WalkPreTranslateTree(HWND hWndStop, MSG* pMsg)
{
// walk from the target window up to the hWndStop window checking
// if any window wants to translate this message
for (HWND hWnd = pMsg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd))
{
CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
if (pWnd != NULL)
{
// target window is a C++ window
if (pWnd->PreTranslateMessage(pMsg)) // 处理它自己的消息
return TRUE; // trapped by target window (eg: accelerators)
}
// got to hWndStop window without interest
//一直到顶层窗口
if (hWnd == hWndStop)
break;
}
return FALSE; // no special processing
}