以下内容摘自<<Windows核心编程>>:
概要:
SendMessage对于在同一个线程中调用的话,直接调用的是当前线程所属窗口的窗口过程函数(WndProc);如果是跨线程调用SendMessage(),那个这个消息会被放在登记消息队列.登记消息队列中的消息优先级越高,越是能够得到优先响应,处理完成后返回给发送者线程.
详细内容:
如果调用SendMessage()的线程向该线程所建立的窗口发送一个消息, SendMessage()就很简单:它只是调用指定窗口的窗口过程,将其作为一个子例程,当窗口过程完成对消息的处理时,它向SendMessage()返回一个值,SendMessage()再将这个返回值 返回给调用线程即当前线程;
但是,当一个线程向其他线程所建立的窗口发送消息,SendMessage()所做的工作就复杂很多(即使两个线程在同一个进程中也是如此).Windows要求建立窗口的线程处理窗口消息.所以当一个线程调用SendMessage()向一个由其他进程所建立的窗口发送一个消息,也就是向其他线程发送消息,发送者线程不可能处理窗口消息,因为发送者线程不是运行在接收者线程的地址空间中,因此不能访问相应窗口过程的代码和数据.实际上发送者线程要挂起,而由另外的线程处理消息.所以为了向其他线程建立的窗口发送消息,系统必须执行下面将讨论的动作:
首先,发送的消息要追加到接收线程的发送消息队列,同时还为这个线程设定QS_SENDMESSAGE(后面将讨论).其次,如果接收线程已经在执行代码并且没有等待消息(如调用GetMessage,PeekMessage,或WaitMessage)发送的消息不会被处理,系统不能中断线程来立即处理消息.当接收进程在等待消息时,系统首先检查QS_SENDMESSAGE唤醒标志是否被设定,如果是,系统扫描发送消息队列中消息的列表,并找到第一个发送的消息.有可能在这个队列中有几个发送的消息.例如几个线程可以同时向同一个窗口分别发送消息.当发生这样的事时,系统只是将这些消息追加到接收线程的发送消息队列中.
当接收线程等待消息时,系统从发送消息队列中取出第一个消息并调用适当的窗口过程来处理消息.如果在发送消息队列再没有消息了,则QS_SENDMESSAG标志被关闭.当接收线程处理消息的时候,调用SendMessage()函数的发送者线程被置为空闲状态(idle),等待一个消息出现在它的应答消息队列中.在发送的消息处理之后,窗口过程的返回值被登记到发送者线程的应答消息队列中.发送线程现在被唤醒,取出包含在应答消息队列中的返回值.这个返回值就是调用SendMessage()的返回值.这时,发送线程继续正常运行.
当一个线程等待SendMessage()返回时,它基本上是处于空闲状态,但它可以执行一个任务:如果系统中另外一个线程向一个窗口发送消息,这个窗口是由这个等待SendMessage()函数返回的线程所建立的,则系统要立即处理发送的消息,在这种情况下,系统不必等待线程去调用GetMessage,PeekMessage或WaitMessage.
SendMessage到底是如何工作的?