把Delphi里TThread的WaitFor函数转化成C++代码,就会是下面这个样子。
-
BOOLTThread::WaitFor(HANDLEhThread)
- {
- MSGmsg;
-
HANDLEhandle[1];
- handle[0]=hThread;
-
DWORDdwWaitResult=0;
-
do
- {
-
-
-
if(dwWaitResult==WAIT_OBJECT_0+1)
- PeekMessage(&msg,0,0,0,PM_NOREMOVE);
-
dwWaitResult=MsgWaitForMultipleObjects(1,handle,false,1000,QS_SENDMESSAGE);
-
if(dwWaitResult==WAIT_FAILED)
-
returnFALSE;
-
if(dwWaitResult==WAIT_TIMEOUT)
- {
- TerminateThread(hThread,0);
-
returnFALSE;
- }
- }
-
while(dwWaitResult!=WAIT_OBJECT_0);
-
returnTRUE;
- }
使我疑惑的是这两行代码
-
if(dwWaitResult==WAIT_OBJECT_0+1)
- PeekMessage(&msg,0,0,0,PM_NOREMOVE);
如果注释所讲是真的,那究竟在哪里处理了其它线程用SendMessage发送过来的消息呢?于是我翻MSDN,查PeekMessage函数,它有这样的解释:
“The PeekMessage function dispatches incoming sent messages, checks the thread message queue for a posted message, and retrieves the message (if any exist).”
我用的是MSND2005,好像再早些的版本里并无“dispatches incoming sent messages”这句。光看这样的注释,实在是太晦涩了些。想起我原来好像发过个讨论这问题的帖子,翻了下发帖记录,还真有,见http://topic.csdn.net/u/20070824/14/d0c96e50-6348-49d3-98e4-9fcc9ead5fdd.html。我当时找到的答案是这样的:
“找到答案了。答案在<<Programming Applications for Microsoft Windows>>第26章的Waking a Thread一节.
The Algorithm for Extracting Messages from a Thread 's Queue
...
1. If the QS_SENDMESSAGE flag is turned on, the system sends the message to the proper window procedure. Both the GetMessage and PeekMessage functions handle this processing internally and do not return to the thread after the window procedure has processed the message; instead, these functions sit and wait for another message to process.
我试着翻译一下:如果QS_SENDMESSAGE标志位有效,系统发送消息(即其它线程通过SendMessage发送过来的消息)到对应的窗口过程。GetMessage和PeekMessage函数在内部进行这样的处理,一直等到窗口过程处理完之后才会返回。也就是说,这些函数(GetMessage和PeekMessage)坐下来等到其它的消息处理完。”
书本里的解释已经很清楚详细了,我当时的译文有错误,原文是说GetMessage和PeekMessage调用窗口过程处理完SendMessage发送过来的消息后,还会继续坐下来等自己消息队列里的消息。
理论有了,结合着看看上面WaitFor的代码。MsgWaitForMultipleObjects的最后一个参数QS_SENDMESSAGE指明了如果其它有其它线程用SendMessage向本线程的窗口发送消息,MsgWaitForMultipleObjects就会立即返回,返回值为WAIT_OBJECT_0 + nCount(本例中nCount值为1),接下来就轮到PeekMessage登场了。
PeekMessage其实做了两件事,一件是把收到的消息标示为旧消息。见MSND里对MsgWaitForMultipleObjects返回值的解释:
“Functions such as PeekMessage, GetMessage, and WaitMessage mark messages in the queue as old messages.”
另一件就是把SendMessage发送过来的消息dispatch到窗口过程。下一次调用MsgWaitForMultipleObjects时队列里便没有新消息了。
那变旧的消息还在队列里吗?答案是不在。因为用SendMessage发送过来的消息根本就不会进应用程序的消息队列。在PeekMessage调用窗口过程处理完它时,它便消失了。而我们也很轻松的就知道,SendMessage函数把QS_SENDMESSAGE这个标志turn on了,PeekMessage和GetMessage还有WaitMessage把这个标志turn off了,把QS_SENDMESSAGE标志turn off的过程就是把消息变旧的过程。
分享到:
相关推荐
本主题将深入探讨`FindWindow`、`PostMessage`、`SendMessage`以及`PeekMessage`这四个关键函数,它们在Windows API中扮演着重要的角色,特别是在线程间通信和窗口消息处理方面。 1. **FindWindow**: `FindWindow...
本篇主要介绍的是`PeekMessage`函数,它是Windows API中用于消息处理的一个关键部分,特别是在多线程编程中。 `PeekMessage`函数的主要作用是检查指定线程的消息队列,它不会阻塞调用线程,即使没有消息也会立即...
每当一个应用程序调用`GetMessage`或`PeekMessage`函数来获取待处理的消息时,如果系统中已经安装了相应的钩子,那么这些钩子就会先于目标窗口捕获消息。这意味着钩子函数可以优先处理消息,并根据需要决定是否将...
《深入解析win32appdllpeekmessage0.1:Windows 32位应用程序与PeekMessage函数的应用》 在Windows编程领域,理解操作系统的核心机制以及如何有效地与之交互至关重要。"win32appdllpeekmessage0.1.rar"是一个...
在IT领域,串口通信是一种常见且重要的技术,特别是在嵌入式系统、设备控制和数据交换中。本文将深入探讨“VC串口通信教程”所涵盖的知识点,包括串口通信的基本概念,以及如何在VC++环境下使用不同的方法实现串口...
那么有什么办法可以解决吗? 虽然我们在制作模态窗口中的页面时,可以使用普通的IE窗口来访问其内容和调试脚本。可是当我的页面完成,并装载入模态窗口并依赖一系列的输入数据后,我们要对他进行debug,就变得很不...
在这个“多线程(姐姐监督弟弟做作业)”的例子中,我们看到一个巧妙地应用了多线程概念的情景。在这个场景中,有两个线程,分别代表姐姐和弟弟。弟弟的线程负责做作业,而姐姐的线程则可以随时介入,就像在现实生活...
在IT领域,尤其是在Windows应用程序开发中,`GetMessage`和`PeekMessage`函数是两个重要的消息处理函数,主要用于从消息队列中获取并处理消息。这两个函数在处理用户交互和程序响应性方面起着关键作用。让我们深入...
本Demo提供的解决方案是通过合理利用`DoEvents()`函数和`PeekMessage()`函数,以及引入多线程技术来改善这种情况。 首先,让我们深入理解这两个函数的作用: 1. `DoEvents()`:这是一个MFC中的函数,它允许UI线程...
具体来说,通过使用`PeekMessage`和`DispatchMessage`函数组合,可以达到与VB中DoEvents相似的效果。 #### PeekMessage函数 `PeekMessage`函数用于检查是否有待处理的消息存在消息队列中,而不会从队列中移除消息...
在描述中提到的“windowsmain no getmessage modify the peekmessage”,这似乎在讨论对`GetMessage`和`PeekMessage`函数的修改,这两个函数是Windows消息循环的关键部分。 1. **WindowsMain窗口过程**:在Windows...
记录键盘操作。键盘钩子记录键盘鼠标操作,监控和设定查证。
`PostThreadMessage`、`_beginthreadex`和`PeekMessage`是Windows API中的函数,它们用于实现线程间通信和线程管理。这里我们将深入探讨这些知识点。 首先,`_beginthreadex`是Windows API提供的创建新线程的函数,...
PeekMessage函数在没有消息的时候会立刻返回,可以在没有消息的时候处理其他任务,但是CPU占用率较高。大多数游戏都使用PeekMessage函数,以便快速响应用户的输入。 结论 PreTranslateMessage函数是MFC中一个非常...
在批量提取QQ在线用户的场景中,可能并不直接使用到`PeekMessage`,但它的作用在于提供了一种线程间通信的方式,可以用于监控程序的运行状态,或者在多线程环境下控制程序的执行流程。 总的来说,这个易语言项目...
1. **消息处理的时机**:PostMessage将消息放入目标线程的消息队列中,由目标线程在空闲时通过`PeekMessage`或`GetMessage`函数获取并处理。而SendMessage则直接将消息交付给目标线程的窗口过程,无需经过消息队列。...
2. **PeekMessage**: 与`GetMessage`类似,但不同的是它不会将消息从队列中移除,只是检查消息队列中是否有消息。 3. **TranslateMessage**: 这个函数用于将虚拟键消息转换成字符消息,例如键盘输入的字符。 4. **...
在16位的Windows 3.x系统中,采用的是协同多任务模型,这意味着应用程序通过调用特定函数(如GetMessage、PeekMessage、WaitMessage或Yield)自愿交出CPU控制权。如果程序长时间不调用这些函数,会导致系统无法响应...
WH_HARDWARE 线程、系统 每当调用GetMessage或PeekMessage函数时,如果从消息队列中得到的是非鼠标和键盘消息,则调用钩子函数 WH_JOURNALRECORD 系统 日志记录钩子,用来记录发送给系统消息队列的所有消息 WH_...
4. **PeekMessage函数**:在Windows编程中,`PeekMessage`函数是用于处理消息队列的。虽然这个函数在“查找在线QQ号码群发”这个场景中可能不是直接相关的,但如果我们在编写群发消息的后台程序时,可能会用到`...