PostMessage与SendMessage的区别

PostMessage将消息放入消息队列中,不等待消息处理,立即返回,消息队列里的消息通过调用GetMessage和PeekMessage取得。

函数原型:B00L PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
参数
  hWnd:其窗口程序接收消息的窗口的句柄。可取有特定含义的两个值:
    HWND_BROADCAST:消息被寄送到系统的所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口。消息不被寄送到子窗口。
    NULL:此函数的操作和调用参数dwThread设置为当前线程的标识符PostThreadMessage函数一样。
  Msg:指定被寄送的消息。
  wParam:指定附加的消息特定的信息。
  IParam:指定附加的消息特定的信息。
返回值:如果函数调用成功,返回非零值:如果函数调用失败,返回值是零。若想获得更多的错误信息,请调用GetLastError函数。
备注:需要以 HWND_BROADCAST方式通信的应用程序应当用函数 RegisterwindwosMessage来获得应用程序间通信的独特的消息。
  如果发送一个低于WM_USER范围的消息给异步消息函数(PostMessage.SendNotifyMessage,SendMesssgeCallback),消息参数不能包含指针。否则,操作将会失败。函数将再接收线程处理消息之前返回,发送者将在内存被使用之前释放。

  PostMessage消息中传值尽量避免传指针,因为消息投递到目标线程消息队列后,程序继续执行,而此时消息并没有马上处理,等到线程处理此消息时,指针内容可能已经释放,或者发生改变。

 

SendMessage发送消息,等到消息被处理后返回,即消息处理函数返回后,SendMessage才会继续执行下去;

函数原型:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);
参数:
  hWnd:其窗口程序将接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。
  Msg:指定被发送的消息。
  wParam:指定附加的消息指定信息。
  IParam:指定附加的消息指定信息。
返回值:返回值指定消息处理的结果,依赖于所发送的消息,即消息处理函数返回值。
备注:需要用HWND_BROADCAST通信的应用程序应当使用函数RegisterWindowMessage来为应用程序间的通信取得一个唯一的消息。
  如果指定的窗口是由调用线程创建的,则窗口程序立即作为子程序调用。如果指定的窗口是由不同线程创建的,则系统切换到该线程并调用恰当的窗口程序。线程间的消息只有在线程执行消息检索代码时才被处理。发送线程被阻塞直到接收线程处理完消息为止。

 

SendMessageTimeout等待一段时间之后,消息处理函数没有返回,则放弃等待,继续执行;

 

PostThreadMessage:将一个消息放入(寄送)到指定线程的消息队列里,不等待线程处理消息就返回。

BOOL PostThreadMessage (DWORD idThread,   UINT Msg,   WPARAM wParam,   LPARAM IParam);

idThread:
其消息将被寄送的线程的线程标识符。如果线程没有消息队列,此函数将失败。
当线程第一次调用一个Win 32 USER或GDI函数时,系统创建线程的消息队列。要得到更多的信息,参见备注。

Msg:指定将被寄送的消息的类型。

wParam:指定附加的消息特定信息。

IParam:指定附加的消息特定信息。   返回值: 如果函数调用成功,返回非零值。 如果函数调用失败,返回值是零。   若想获得更多的错误信息,请调用GetLastError函数。 如果idThread不是一个有效的线程标识符或由idThread确定的线程没有消息队列,
GetLastError返回ERROR_INVALID_THREAD_ID。   备注:消息将寄送到的线程必须创建消息队列,否则调用PostThreadMessage会失败。  

如果在同一个线程内,PostMessage发送消息时,消息要先放入线程的消息队列,然后通过消息循环Dispatch到目标窗口。SendMessage发送消息时,系统直接调用目标窗口的消息处理程序,并将结果返回。SendMessage在同一线程中发送消息并不入线程消息队列。 如果在不同线程内,最好用PostThreadMessage代替PostMessage,他工作的很好。SendMessage发送消息到目标窗口所属的线程的消息队列,然后发送消息的线程等待(事实上,他应该还在做一些监测工作,比如监视QS_SENDMESSAGE标志),直到目标窗口处理完并且结果返回,发送消息的线程才继续运行。这是SendMessage的一般情况,事实上,处理过程要复杂的多。比如,当发送消息的线程监测到有别的窗口SendMessage一个消息到来时,他直接调用窗口处理过程(重入),并将处理结果返回(这个过程不需要消息循环中GetMessage等的支持)。

上一篇:阶段1 语言基础+高级_1-2 -面向对象和封装_7一个对象的内存图


下一篇:跨域