消息处理相关函数讲解

来源:互联网 发布:unity3d vr游戏开发 编辑:程序博客网 时间:2024/06/06 00:36

一、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));

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