SendMessage和PostMessage

首先简单从字面区分一下:

Send与Post这两个英文单词的意思:Send有发送的意思,而Post具有投寄的意思。

      Send:  相当于邮寄员,会将快件亲手交给收件人,并且需要收件人签字,他才闪人。而在消息机制中,就是说,系统(邮寄员)会将收到的消息(邮局分发)直接发送到某个窗口的窗口过程(收件人),并且需要该窗口作出处理(收件人签字)才返回,这就是SendMessage
      Post:  相当于邮局、邮筒等等,我们写好信,会将信交给邮局,或投寄到邮筒里,而什么时候发送,发送到哪里都由邮局来处理,我们投寄信件的时候,是不会等候这封信件到达收件人手里,然后才回家的。 而在消息机制中,就是说,系统(我们)将收到的消息(信件)投寄到应用程序的消息循环(相当于邮筒)中,然后就闪人,具体啥时候处理这条消息(啥时候发送邮件),那就得看“办事效率”了。
      区别很明显,SendMessage的消息是不进队列的,而PostMessage的需要排队。 
      值得说明的是:虽然一个要进队,一个不进队,但是最终处理消息的地方都一样:都是系统调用窗口过程进行处理(收件人作出反应)

然后详细看一下具体的细节部分:

Win32 API消息函数:SendMessage

函数功能:该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程 序处理完消息再返回。而函数PostMessage不同,将一个消息寄送到一个线程的消息队列后立即返回。

      函数原型:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);

      参数:

      hWnd:其窗口程序将接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自 身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。

      Msg:指定被发送的消息。
      wParam:指定附加的消息指定信息。
      IParam:指定附加的消息指定信息。
      返回值:返回值指定消息处理的结果,依赖于所发送的消息。
      备注:需要用HWND_BROADCAST通信的应用程序应当使用函数RegisterWindowMessage来为应用程序间的通信取得一个唯一的消 息。
      如果指定的窗口是由调用线程创建的,则窗口程序立即作为子程序调用。如果指定的窗口是由不同线程创建的,则系统切换到该线程并调用恰当的窗口程序。线程间 的消息只有在线程执行消息检索代码时才被处理。发送线程被阻塞直到接收线程处理完消息为止。
      Windows CE:Windows CE不支持Windows桌面平台支持的所有消息。使用SendMesssge之前,要检查发送的消息是否被支持。
      速查:Windows NT:3.1及以上版本:Windows:95及以上版本;Windows CE:1.0及以上版本;头文件:winuser.h;输入库:user32.lib;Unicode:在Windows NT环境下以Unicode和ANSI方式实现。

Win32 API消息函数: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),消息参数不能包含指针。否则,操作将会失 败。函数将再接收线程处理消息之前返回,发送者将在内存被使用之前释放。

      速查:Windows NT: 3.1及以上版本;Windows:95及以上版本;Windows CE:1.0及以上版本;头文件:winuser.h;输入库:user32.lib;Unicode:在Windows NT环境下以Unicode和ANSI方式实现。

在控制别的应用程序的时候,经常需要等待直到某个功能结束,例如:
打开一个窗口-->等待直到窗口结束
这 个时候就可以用到SendMessage
如果在打开这个窗口后仍然需要对该窗口的界面进行设置,比如Edit的value等等,比如:
打 开一个窗口-->控制窗口的control的属性
这个时候就需要PostMessage

使用一个钩子程序截获消息后,使用 SendMessage把消息发送到主处理程序进行处理,但是在主处理程序还没有完成任务的时候,被设置钩子的程序进入了停止的状态,不可以处理
WM_PAINT,
WM_MOVE,
....... 等的基本信息,
必须要等SendMessage发送出的消息完成后,才能继续运行,整个界面一片空白,把钩子消息设置成PostMessage的 发送消息形式后,问题解决!
我查了MSDN对这两个API的定义,
PostMessage只是把消息放入队列,不管其他程序是否处理都返 回,然后继续执行;
而SendMessage必须等待其他程序处理消息后才返回,继续执行。
PostMessage的返回值表示 PostMessage函数执行是否正确;
而SendMessage的返回值表示其他程序处理消息后的返回值。 
使用这两个发送消息函数 的最重要的是要看你的程序是否要对消息的滞后性关注否,PostMessage会造成消息的滞后性,而SendMessage则不会,但如果 SendMessage消息处理失败,则会造成程序停止!

========================================================================================================

1. SendMessage函数要等到消息被处理后才返回

    PostMessage 消息发出后马上返回

2. PostMessage发向目标窗口的消息一定会进入消息队列

    SendMessage向同一线程的窗口发消息,不会进入消息队列,

    SendMessage向其他线程的窗口发消息,则会进入消息队列,

3. PostMessage的返回值表示PostMessage函数执行是否正确,

   SendMessage的返回值表示其他程序处理消息后的返回值

1、SendMessage()和PostMessage().这两个函数几乎是一样的,它们的区别是: 

SendMessage()直接把一个消息发给窗口过程,等消息被处理后才返回。Postmessage()只是把消息发送到消息队列,完成后即返回。

2.1、当调用SendMessage时,接收消息的线程的QS_SENDMESSAGE标志被设置,系统调用相应的窗口过程来处理这个消息。 GetMessage和PeekMessage函数在内部进行这种处理。如果在“发送消息队列”中没有消息了,QS_SENDMESSAGE标志就被关 闭。“发送消息队列”中可能有几个Send过来的消息。例如,几个线程同时向一个窗口发送消息。

2.2、当调用PostMessage时,函数GetMessage或PeekMessage填充传递给它们的Msg结构,函数返回。再调用 DispatchMessage,让相应的窗口过程来处理消息。

2.3、当调用SendMessage时,发送线程和接收线程是同一个线程的时候,SendMessag很简单,只是调用指定窗口的窗口过程。但当 发送线程和接收线程不是同一个线程时,麻烦就大了。因为发送线程和接收线程运行在不同的地址空间中,因此不能访问接受线程中相应窗口过程的代码和数据。其 实这时发送线程要挂起,当接收线程处理Send过来的消息时,发送线程被设置为空闲(idle)状态。在发送的消息处理完成后,窗口过程的返回值被登记到 发送线程的应答消息队列中。发送线程被唤醒,取出包含在应答消息队列中的返回值。这个返回值就是调用SendMessage的返回值,这时,发送线程继续 运行。

2.4、WM_PAINT和WM_TIMER这两个消息的优先级非常低,最低的是WM_TIMER。

2.5、WM_COPYDATA只能Send,不能Post。

========================================================================================================

吕鑫老师介绍的这两个函数部分:

1、SendMessage和PostMessage函数的功能

a)能够向指定的窗口发送窗口消息,既可以是本进程内窗口也可以是其他进程的;

b)既可以发送系统内部消息,消息编号的范围是1~WM_USER-1;

例如:WM_LBUTTONDOW,WM_MOUSEMOVE等;

c)也可以发送非系统消息(开发者定义的消息),范围是WM_USER-0x7FFF。

2、两者的区别:

a)SendMessage是阻塞型函数,PostMessage是非阻塞型函数;

SendMessage用于调用指定窗口的内部程序,直到窗口程序处理完成以后再返回;

PostMessage是将消息寄送到一个窗口内的消息队列后就立即返回。

b)两个函数的返回值不同;

LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);

B00L PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);

SendMessage的返回值依赖于消息处理函数。

c)跨线程或跨进程发送消息,推荐使用PostMessage函数。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值