过程:
Run == CWinApp
-> Run == CWinThread (空闲 OR 有消息到达)
-> PeekMessage == CwinThread::Run
-> PumpMessage == CWinThread::Run(核心)
-> GetMessage == CWinThread::PumpMessage(阻塞等待消息)
-> PreTranslateMessage == CWinThread::PumpMessage
-> TranslateMessage == CWinThread::PumpMessage
-> DispatchMessage == CWinThread::PumpMessage
在CWinApp::Run()中,最后一句是return CWinThread::Run();
在CWinThread::Run()中:无限循环,判断是否空闲与是否有消息,
for (;;)
{
// phase1: check to see if we can do idle work
while (bIdle && !::PeekMessage(&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))
{
bIdle = TRUE;
lIdleCount = 0;
}
} while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
}
利用PeekMessage()来判断消息队列中是否有消息,有的话进入PumpMessage取出消息并处理。
这是SDI处理消息的中心机构,但请注意,它绝对不是核心! 分析一下,在无限循环FOR内部又出现一个WHILE循环
while (bIdle && !::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
以上为:当没消息时,作空闲处理
不空闲时则进入下一个循环:
核心:
消息泵,PumpMessage()读取消息并处理。
PumpMessage()中,
会调用GetMessage()取得一条消息,
然后调用PreTranslateMessage()预处理,
然后TranslateMessage(),
然后DispatchMessage();
当消息队列中有WM_QUIT时,GetMessage()会返回0;这样会使PumpMessage()返回0,回到Run()内部,这里return ExitInstance(); 退出运行。
//************************************************************//
PreTranslateMessage():
MFC消息控制流最具特色的地方是CWnd类的虚拟函数PreTranslateMessage(),通过重载这个函数,我们可以改变MFC的消息控制流程,甚至可以作一个全新的控制流出来。只有穿过消息队列的消息才受PreTranslateMessage()影响,采用SendMessage()或其他类似的方式向窗口直接发送的而不经过消息队列的消息根本不会理睬PreTranslateMessage()的存在。
让PreTranslateMessage()返回TRUE,则不会把该消息分发给窗口函数处理(TranslateMessage, DispatchMessage)
PeekMessage和GetMessage的区别:
GetMessage在没有消息的时候等待消息,cpu当然低
PeekMessage没有消息的时候立刻返回,可以在没有消息的时候可以做其他处理,但cpu占用率一般较高。
大多游戏都用PeekMessage();
TranslateMessage:
函数功能:该函数将虚拟键消息转换为字符消息。字符消息被寄送到调用线程的消息队列里,当下一次线程调用函数GetMessage或PeekMessage时被读出。WM_SYSKEYDOWN和WM_SYSKEYUP组合产生一个WM_SYSCHAR或 WM_SYSDEADCHAR消息。TtanslateMessage为那些由键盘驱动器映射为ASCll字符的键产生WM_CHAR消息
DispatchMessage
函数功能:该函数调度一个消息给窗口程序。通常调度从GetMessage取得的消息。消息被调度到的窗口程序即是MainProc()函数。