PeekMessage与GetMessage PumpMessage()
来源:互联网 发布:atan2函数java 编辑:程序博客网 时间:2024/06/11 01:49
通过GetMessage或PeekMessage函数得到消息并推动消息的处理!
其函数原型如下:
//thrdcore.cpp BOOL CWinThread::PumpMessage()
{ ASSERT_VALID(this); //如果是WM_QUIT就退出函数(return FALSE),这将导致程序结束.
if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))
{
#ifdef _DEBUG if (afxTraceFlags & traceAppMsg) TRACE0("CWinThread::PumpMessage - Received WM_QUIT.n"); m_nDisablePumpCount++; // application must die // Note: prevents calling message loop things in 'ExitInstance' // will never be decremented #endif return FALSE; }
#ifdef _DEBUG if (m_nDisablePumpCount != 0)
{ TRACE0("Error: CWinThread::PumpMessage called when not permitted.n"); ASSERT(FALSE); }
#endif
#ifdef _DEBUG if (afxTraceFlags & traceAppMsg)
_AfxTraceMsg(_T("PumpMessage"), &m_msgCur); #endif // process this message if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur))
{ ::TranslateMessage(&m_msgCur); //键转换 ::DispatchMessage(&m_msgCur); //派送消息 }
}
如下实例:非对话框程序的消息循环机制
//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 On
Idle 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));
} //无限循环,退出条件是收到WM_QUIT消息。 ASSERT(FALSE); // not reachable }
这是一个无限循环,他的退出条件是收到WM_QUIT消息:
if (!PumpMessage())
return ExitInstance();
在PumpMessage中,如果收到WM_QUIT消息,那么返回FALSE,所以ExitInstance()函数执行,跳出循环,返回程序的退出代码。所以,一个程序要退出,只用在代码中调用函数
VOID PostQuitMessage( int nExitCode )。指定退出代码nExitCode就可以退出程序。
下面讨论一下这个函数Run的流程,分两步:
1,第一个内循环phase1。bIdle代表程序是否空闲。他的意思就是,如果程序是空闲并且消息队列中没有要处理的消息,那么调用虚函数On
NOTE:MS用临时对象是出于效率上的考虑,使内存有效利用,并能够在空闲时自动撤销资源。关于由句柄转换成对象,可以有若干种方法。一般是先申明一个对象obj,然后使用obj.Attatch来和一个句柄绑定。这样产生的对象是永久的,你必须用obj.Detach来释放对象。
2,第二个内循环phase2。在这个循环内先启动消息泵(PumpMessage),如果不是WM_QUIT消息,消息泵将消息发送出去(::DispatchMessage)。消息的目的地是消息结构中的hwnd字段所对应的窗口。其中是指使用PumpMessage函数自己设计了消息处理过程,我们不需要知道PumpMessage函数内部做了什么处理(当然,经过之前的PumpMessage源码解析你也知道了),只要知道它就是消息处理的核心动力,起到取消息、转换消息并发送消息的作用就行了!而while循环的::PeekMessage(&msg, NULL,0,0,PM_NOREMOVE)只是检测消息队列中是否存在消息罢了(PM_NOREMOVE说明了这一点),如果有消息就调用PumpMessage去消息并处理发送,若果消息队列为空则推出循环。void CProgressWnd::PeekAndPump(BOOL bCancelOnESCkey /*= TRUE*/){ if (m_bModal && ::GetFocus() != m_hWnd) SetFocus(); MSG msg; while (::PeekMessage(&msg, NULL,0,0,PM_NOREMOVE)) { if (bCancelOnESCkey && (msg.message == WM_CHAR) && (msg.wParam == VK_ESCAPE)) OnCancel(); // Cancel button disabled if modal, so we fake it. if (m_bModal && (msg.message == WM_LBUTTONUP)) { CRect rect; m_CancelButton.GetWindowRect(rect); if (rect.PtInRect(msg.pt)) OnCancel(); } if (!AfxGetApp()->PumpMessage()) { ::PostQuitMessage(0); return; } }}
- PeekMessage与GetMessage PumpMessage()
- GetMessage与PeekMessage深入浅出
- PeekMessage与GetMessage
- PeekMessage 与 GetMessage 区别
- GetMessage与Peekmessage区别
- GetMessage与Peekmessage区别
- PeekMessage与GetMessage .
- PeekMessage与GetMessage区别
- PeekMessage()与GetMessage() 区别
- PeekMessage与GetMessage区别
- GetMessage与PeekMessage区别
- PeekMessage()与GetMessage()
- 对比PeekMessage与GetMessage
- PeekMessage与GetMessage
- GetMessage 与 PeekMessage 区别
- PeekMessage 与 GetMessage
- PeekMessage与GetMessage
- PeekMessage与GetMessage区别
- HttpServletResponse实现网页定时刷新并跳转(三)
- VUE 缺省页父子组件
- hdu 2112 Today
- 一维多项式求值
- ssh: Could not resolve hostname ...
- PeekMessage与GetMessage PumpMessage()
- 大二学习开始
- 交互设计师到底是干嘛的
- UEFI 模式下win10安装ubuntu16.04双系统教程
- 【Spring源码学习】Spring框架结构
- 这样走能实现读博梦想吗?
- 今天又犯二了。
- scanf
- 话说linux 下的pthread 内存问题 (Valgrind 检测 及定位排除)