[转]关于VC++ MFC中的空闲Idle处理机制!
2017-05-13 15:23
441 查看
关键词:
先根据空闲标志以及消息队列是否为空这两个条件判断当前线程是否处于空闲状态(这个“空闲”的含义同操作系统的含义不同,是MFC自己所谓的“空闲”),如果是,就调用CWinThread::OnIdle(),这也是我们比较熟悉的一个虚拟函数。
在这里,我们发现,MFC不是调用GetMessage()从线程消息队列中取消息,而是调用PeekMessage()。其原因在 于,GetMessage()是一个具有同步行为的函数,如果消息队列中没有消息,GetMessage()会一直阻塞,使得线程处于睡眠状态,直到消息 队列中有一条或多条消息,操作系统才会唤醒该线程,GetMessage()才会返回,如果线程处于睡眠状态了,就不会使线程具有MFC所谓的“空闲”状 态了;而PeekMessage()则是一个具有异步行为的函数,如果消息队列中没有消息,它马上返回0,不会导致线程处于睡眠状态。
首先,PumpMessage()调用GetMessage()从消息队列中取一条消息,由于PumpMessage()是在消息队列中有消息的时候才被调用的,所以GetMessage()会马上返回, 根据其返回值,判断当前取出的消息是不是WM_QUIT消息(这个消息一般对是通过调用PostQuitMessage()放入线程消息队列的),如果 是,就返回FALSE,CWinThread::Run()该退出了,CWinThread::Run()直接调用 CWinThread::ExitInstance()退出应用程序。在GetMessage()的后面是我们所熟悉的 TranslateMessage()和DispatchMessage()函数。
可以看出,是否调用TranslateMessage()和DispatchMessage()是由一个名称为PreTranslateMessage()函数的返回值决定的,如果该函数返回TRUE,则不会把该消息分发给窗口函数处理。
文章转载自:罗索实验室 [http://www.rosoo.net/a/201102/10850.html]
先根据空闲标志以及消息队列是否为空这两个条件判断当前线程是否处于空闲状态(这个“空闲”的含义同操作系统的含义不同,是MFC自己所谓的“空闲”),如果是,就调用CWinThread::OnIdle(),这也是我们比较熟悉的一个虚拟函数。
如果不是,从消息队列中取出消息,进行处理,直到消息队列为空。 /thrdcore.cpp // main running routine until thread exits int CWinThread::Run() { ASSERT_VALID(this); // 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(&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)); } ASSERT(FALSE); // not reachable }
在这里,我们发现,MFC不是调用GetMessage()从线程消息队列中取消息,而是调用PeekMessage()。其原因在 于,GetMessage()是一个具有同步行为的函数,如果消息队列中没有消息,GetMessage()会一直阻塞,使得线程处于睡眠状态,直到消息 队列中有一条或多条消息,操作系统才会唤醒该线程,GetMessage()才会返回,如果线程处于睡眠状态了,就不会使线程具有MFC所谓的“空闲”状 态了;而PeekMessage()则是一个具有异步行为的函数,如果消息队列中没有消息,它马上返回0,不会导致线程处于睡眠状态。
BOOL CWinThread::PumpMessage() { ASSERT_VALID(this); if (!::GetMessage(&m_msgCur, NULL, NULL, NULL)) return FALSE; // process this message if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur)) { ::TranslateMessage(&m_msgCur); ::DispatchMessage(&m_msgCur); } return TRUE; }
首先,PumpMessage()调用GetMessage()从消息队列中取一条消息,由于PumpMessage()是在消息队列中有消息的时候才被调用的,所以GetMessage()会马上返回, 根据其返回值,判断当前取出的消息是不是WM_QUIT消息(这个消息一般对是通过调用PostQuitMessage()放入线程消息队列的),如果 是,就返回FALSE,CWinThread::Run()该退出了,CWinThread::Run()直接调用 CWinThread::ExitInstance()退出应用程序。在GetMessage()的后面是我们所熟悉的 TranslateMessage()和DispatchMessage()函数。
可以看出,是否调用TranslateMessage()和DispatchMessage()是由一个名称为PreTranslateMessage()函数的返回值决定的,如果该函数返回TRUE,则不会把该消息分发给窗口函数处理。
文章转载自:罗索实验室 [http://www.rosoo.net/a/201102/10850.html]
相关文章推荐
- [转]关于VC++ MFC中的空闲Idle处理机制!
- 【VC编程】笔记3---使用Win32SDK编程,模仿MFC的消息映射处理机制
- [转][VC/MFC]关于内存映射文件技术处理大文件的读写-例
- 关于《VC++权威剖析:MFC的原理、机制与开发实例》中的函数重载
- [转][VC/MFC]关于内存映射文件技术处理大文件的读写
- 深入剖析MFC中对于Windows消息处理、运行机制 选择自 mahongxi 的 Blog
- [C++ VC MFC] MFC消息响应机制
- 孙鑫VC++讲座笔记-(4)MFC消息映射机制的剖析
- 关于对于VC/MFC/ATL的评论问题
- 进一步详细说明MFC中Win消息处理、运行机制
- java .net MFC QT事件处理机制
- 关于MFC控件变量错误的处理
- 孙鑫VC++讲座笔记-(4)MFC消息映射机制的剖析
- 深入剖析MFC中Windows消息处理、运行机制
- MFC/VC: 关于内存问题。
- 关于c#中的消息处理函数和vc中的消息处理函数区别
- 关于vc2005编译asm文件出错的一个处理方法
- 关于c#中的事件处理机制
- 孙鑫VC++讲座笔记-(4)MFC消息映射机制的剖析
- 关于c#中的事件处理机制