消息处理相关函数讲解

一、SendMessage :该函数将指定的消息发送到一个或多个窗口(以下消息发送函数皆是如此不必多言)。如果指定窗口由调用线程创建,那么窗口过程会被当成一个子程序立即调用。如果指定窗口由另外一个线程创建,那么系统会切换到那个线程,并且调用合适的窗口过程。在线程之间传递的消息仅仅当接收线程执行message retrieval code才会被处理。发送线程会被堵塞直到接收线程处理完消息。但是,发送线程在等待的同时会处理收到的nonqueued messages 。为了阻止这一点,使用带有SMTO_BLOCK参数 的SendMessageTimeout。我调用SendMessage向另外一个线程窗口发message,本来以为他会一直block住,但是他却调用了另外一个消息的处理程序,导致了行为不正确。所以一定要小心使用SendMessage发给其他线程的窗口。
把pWnd->SendMessage(MSG_LOG_MESSAGE, nMsgType, (LPARAM)(LPCTSTR)m_cstrMessage);改成了
::SendMessageTimeout(hWnd,MSG_LOG_MESSAGE, nMsgType, (LPARAM)(LPCTSTR)m_cstrMessage,SMTO_BLOCK,15000,0); 解决了这个bug.

二、SendMessageTimeout : 此函数为指定的窗口调用窗口程序,如果指定的窗口属于不同的线程,直到窗口程序处理完消息或指定的超时周期结束函数才返回(怀疑消息被撤消)。如果接收消息的窗口和当前线程属于同一个队列,窗口程序立即调用,超时值无用。 参数fuFlags常用参数值:1.SMTO_ABORTIFHUNG如果接收进程处于“hung”状态,不等待超时周期结束就返回。 2.SMTO_BLOCK阻止调用线程处理其他任何请求,直到函数返回。 3.SMTO_NORMAL调用线程等待函数返回时,不被阻止处理其他请求。

三、SendMessageCallback:此函数为指定的窗口调用窗口程序,并立即返回。当窗口程序处理完消息后,系统调用指定的回调函数,将消息处理的结果和一个应用程序定义的值传给回调函数。参见SendAsyncProc可得到合适的回调函数的信息。要以HWND_BROADCAST方式通信的应用程序应当用函数RegisterWindwosMessage来获得应用程序间通信的独特的消息。此回调函数仅当调用SendMessagecallback的线程调用GetMessage,PeekMessage或WaitMessage时调用。

四、SendNotifyMessage:该函数将指定的消息发送到一个窗口。如果该窗口是由调用线程创建的;此函数为该窗口调用窗口程序,并等待窗口程序处理完消息后再返回。如果该窗口是由不同的线程创建的,此函数将消息传给该窗口程序,并立即返回,不等待窗口程序处理完消息。

五、PostMessage:该函数将一个消息放入(寄送)到与指定窗口创建的线程相联系消息队列里,不等待线程处理消息就返回,是异步消息模式。消息队列里的消息通过调用GetMessage和PeekMessage取得。返回值:如果函数调用成功,返回非零值:如果函数调用失败,返回值是零。若想获得更多的错误信息,请调用GetLastError函数。

备注:如果发送一个低于WM_USER范围的消息给异步消息函数(PostMessage,SendNotifyMessage,SendMesssgeCallback),消息参数不能包含指针(但如果动态数据对象不被释放呢?)。否则,操作将会失败。函数将在接收线程处理消息之前返回,发送者将在内存被使用之前释放。

六、InsendMessage:该函数决定当前窗口程序是否处理另一个线程调用SendMesssge(在相同进程或不同进程)发送来的消息。
参数:必无;返回值:如果窗口程序处理另一个线程调用SendMessage发送来的消息,返回非零值。如果窗口程序不处理另一个线程调用SendMessage发送来的消息,返回值是零。 nsendMessageEx:此函数与InsendMesssge相似,但另外提供了如何发送消息的信息。

七、PeekMessage:此该函数为一个消息检查线程消息队列,并将该消息(如果存在)放于指定的结构。和函数GetMessage不一样的是,函数PeekMesssge在返回前不等待消息被放到队列里。 常数WM_KEYFIRST和WMKEYLAST可作为过滤值取得所有键盘消息;常数WM_MOUSEFIRST和WM_MOUSELAST可用来接收所有的鼠标消息。

八、GetMessage:从调用线程的消息队列里取得一个消息并将其放于指定的结构。此函数可取得与指定窗口联系的消息和由PostThreadMesssge寄送的线程消息。此函数接收一定范围的消息值。GetMessage不接收属于其他线程或应用程序的消息。获取消息成功后,线程将从消息队列中删除该消息。函数会一直等待直到有消息到来才有返回值。应用程序通常用返回值来确定是否终止主消息循环并退出程序。

备注:PeekMessage返回TRUE的条件是有消息,如果没有消息返回FALSE ; GetMessage返回TRUE的条件是有消息且该消息不为WM_QUIT,返回FALSE的条件是有消息且该消息为WM_QUIT。通常用peek扔掉不想要的消息:while(PeekMessage (&msg, NULL(HWND), WM_MOUSEFIRST,WM_MOUSELAST, PM_REMOVE));

另外:当父窗口和子窗口处于不同线程的情况下消息发送易使线程死锁,可能因为父窗口重绘时会通知子窗口等情况的缘故吧。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C#中SendMessage和PostMessage的参数传递 在C#中可以使用Window API提供的SendMessage和PostMessage来传递参数。两者的区别简单介绍下:返回值的不同,我们先看一下 MSDN 里的声明: LRESULT SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ); BOOL PostMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ); 其中 4 个参数的意义是一样的,返回值类型不同(其实从数据上看他们一样是一个 32 位的数,只是意义不一样),LRESULT 表示的是消息处理后的返回值,BOOL 表示的是消息是不是 Post 成功。 2、PostMessage 是异步的,SendMessage 是同步的。 PostMessage 只把消息放入队列,不管消息是否被处理就返回,消息可能不被处理;而 SendMessage 等待消息处理完了之后才返回,如果消息不被处理,发送消息的线程将一直被阻塞。 3、如果在同一个线程内,SendMessage 发送消息时,由 USER32.DLL 模块调用目标窗口的消息处理程序,并将结果返回。SendMessage 在同一线程中发送消息并不入线程消息队列。PostMessage 发送消息时,消息要先放入线程的消息队列,然后通过消息循环分派到目标窗口(DispatchMessage)。 如果在不同线程内,SendMessage 发送消息到目标窗口所属线程的消息队列,然后发送消息的线程在 USER32.DLL 模块内监视和等待消息处理,直到目标窗口处理完返回。SendMessage 在返回前还做了很多工作,比如,响应别的线程向它 SendMessage。Post 到别的线程时,最好用 PostThreadMessage 代替 PostMessage,PostMessage 的 hWnd 参数可以是 NULL,等效于 PostThreadMessage + GetCurrentThreadId。Post WM_QUIT 时,应使用 PostQuitMessage 代替。 4、系统只整编(marshal)系统消息(0 到 WM_USER 之间的消息),发送用户消息(WM_USER 以上)到别的进程时,需要自己做整编。 用 PostMessage、SendNotifyMessage、SendMessageCallback 等异步函数发送系统消息时,参数里不可以使用指针,因为发送者并不等待消息处理就返回,接受者还没处理指针就已经被释放了。 5、在 Windows 2000/XP 里,每个消息队列最多只能存放 10,000 个 Post 的消息,超过的还没被处理的将不会被处理,直接丢掉。这个值可以改得更大:[HKEY_LOCAL_MACHINE/SOFTWARE/ Microsoft/Windows NT/CurrentVersion/Windows] USERPostMessageLimit,最小可以是 4000。 PostMessage只负责将消息放到消息队列中,不确定何时及是否处理 SendMessage要等到受到消息处理的返回码(DWord类型)后才继续 PostMessage执行后马上返回 SendMessage必须等到消息处理后才会返回。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值