请熟悉消息的高人帮忙解释下这个消息泵!

teleinfor 2009-06-05 09:12:10
消息泵1:
BOOL CMainFrame::PeekAndPump(void)
{
MSG msg;

// message pump
while(::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
{
if(!AfxGetApp()->PumpMessage())
{
::PostQuitMessage(0);
return FALSE;
}
}

// 模拟空闲处理
LONG iCount = 0;
while(AfxGetApp()->OnIdle(iCount++));

return TRUE;
}

这里注意使用的是PM_NOREMOVE


BOOL CMainFrame::PeekAndPump(void)
{
MSG message;
// message pump
while(::PeekMessage(&message,NULL,0,0,PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}


// 模拟空闲处理
LONG iCount = 0;
while(AfxGetApp()->OnIdle(iCount++));

return TRUE;
}

注意这里使用的是PM_REMOVE

连个消息泵的区别?如何理解MSG执行思路?为何一个PM_REMOVE另一个PM_NOREMOVE。

是不是第一个方法的把消息从队列REMOVE放在了AfxGetApp()->PumpMessage()???
...全文
128 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
gg606 2009-11-09
  • 打赏
  • 举报
回复
CWinThread 的 PumpMessage()是这样的:
BOOL CWinThread::PumpMessage()
{
ASSERT_VALID(this);

if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))
{
return FALSE;
}

if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur))
{
::TranslateMessage(&m_msgCur);
::DispatchMessage(&m_msgCur);
}
return TRUE;
}


很不解:为什么把消息泵写到窗口类里来呢?很少见。
第一个例子里,PumpMessage()返回FALSE说明已经收到了WM_QUIT 消息,为什么还要再用PostQuitMessage发送一个呢?CMainFrame难道不是主线程的主窗口?

回答你的问题:
第一个只是看一下消息队列,并不处理,所以不移除,移除了线程或APP类的相关函数就没法处理了。
第二个在那里对消息进行了翻译和派送,所以就移除了。
wocow3 2009-11-09
  • 打赏
  • 举报
回复
自己写的泵?
1.有消息等待,在AfxGetApp()->PumpMessage();
2.不可取,无消息等待,影响效率
  • 打赏
  • 举报
回复
四楼提示的不错。
jxcyly1985 2009-11-09
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 teleinfor 的回复:]
多谢楼上的xd。

我也猜测应该哪里用到了REMOVE,就是不确定。对消息的理解还没有彻底。我再看看。
[/Quote]
PumpMessage的源码,在里面进行了Remove的操作
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;
}
teleinfor 2009-06-08
  • 打赏
  • 举报
回复
多谢楼上的xd。

我也猜测应该哪里用到了REMOVE,就是不确定。对消息的理解还没有彻底。我再看看。
keristef 2009-06-08
  • 打赏
  • 举报
回复
// message pump 
while(::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
{
if(!AfxGetApp()->PumpMessage())
{
::PostQuitMessage(0);
return FALSE;
}
}


这段代码中AfxGetApp()->PumpMessage())里面应该用了REMOVE或者GetMessage把消息取走,

至于为什么调用AfxGetApp()->PumpMessage())而不是下面的那段代码那就不知道了,AfxGetApp()->PumpMessage())里面应该做了特殊处理,楼主自己跟进去看看。
Ryanwen 2009-06-08
  • 打赏
  • 举报
回复
深入探讨MFC消息循环和消息泵
http://hi.baidu.com/passionme/blog/item/ce5fde3f4c6549c67c1e71a9.html
lose_forest 2009-06-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 teleinfor 的回复:]
我知道是REMOVE。看看问题再答题。

这里为啥两个地方一个REMOVE 一个是NOREMOVE。
[/Quote]

设计需要
teleinfor 2009-06-05
  • 打赏
  • 举报
回复
我知道是REMOVE。看看问题再答题。

这里为啥两个地方一个REMOVE 一个是NOREMOVE。
bragi523 2009-06-05
  • 打赏
  • 举报
回复
[Quote=引用楼主 teleinfor 的帖子:]
注意这里使用的是PM_REMOVE

连个消息泵的区别?如何理解MSG执行思路?为何一个PM_REMOVE另一个PM_NOREMOVE。

是不是第一个方法的把消息从队列REMOVE放在了AfxGetApp()->PumpMessage()???
[/Quote]

就是是否把消息从队列中移除

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧