admin 管理员组

文章数量: 1184232

PostMessage,SendMessage,GetMessage,PeekMessage,TranslateMessage,DispatchMessage的用法集合

SendMessage函数功能描述:将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口过程,直到窗口过程处理完消息后才返回。

Postmessage函数则是将消息放入消息队列里,并立即返回。

PostThreadMessage函数: 

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


     它可以用于线程之间的异步通讯,因为它不用等待调用者返回,

.常见问题
1)使用SendMessage来实现剪切、复制和粘贴

SendMessage(hwnd, WM_COPY, 0, 0);
SendMessage(hwnd, WM_CUT, 0, 0);
SendMessage(hwnd, WM_PASTE, 0, 0);

2)SendMessage与PostMessage的区别
PostMessage将消息放入消息队列后马上返回,而SendMessage直到窗口过程处理完消息后才返回,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 代替。


来源: <.html>

4)SendMessage发送WM_COPYDATA消息在进程间传送数据
WM_COPYDATA消息主要目的是允许在进程间传递少量只读数据。SDK文档推荐用户使用SendMessage()函数,接收方在数据复制完成前不返回,这样发送方就不可能删除和修改数据。
例如:

std:string strData = "VC COM";
COPYDATASTRUCT cds;
cds.dwData = 0;
cds.cbData = strData.Length();
cds.lpData = strData.c_str();
::SendMessage(hwnd, WM_COPYDATA, NULL, (LPARAM)&cds);

3、PostThreadMessage有时会失败,报1444错误(Invalid thread identifier. ),其实这不一定是线程不存在的原因,也有可能是线程不存在消息队列(message queue)造成的。事实上,并不是每个thread都有message queue,那如何让thread具有呢? 答案是,至少调用message相关的function一次,比如GetMessage,PeekMessage
4、如果是postthreadmessage动态分配的memory给另外一个thread,要注意内存的正确释放(注意,此处不释放可能导致内存泄露)。并且PostThreadMessage不能够post WM_COPYDATE之类的同步消息,否则会报错!
来源: </>

GetMessage、PeekMessage、WaitMessage ,消息的接收主要有3个函数,该函数用于查看应用程序的 消息队列 。 消息的接收主要有3个函数: GetMessage、PeekMessage、WaitMessageGetMessage 原型如下:
BOOL GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax);
PeekMessage 原型如下:
BOOL PeekMessage(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax,
UINT wRemoveMsg
);
该函数用于查看应用程序的消息队列,如果其中有消息就将其放入lpMsg所指的结构中,不过,与GetMessage不同的是, PeekMessage 函数 不会等到有消息放入队列时才返回 。同样,如果hWnd为NULL,则PeekMessage 获取属于调用该函数应用程序的任一窗口的消息 ,如果hWnd=-1,那么函数 只返回把hWnd参数为NULL的PostAppMessage函数送去的消息 。如果 wMsgFilterMin和wMsgFilterMax都是0,则PeekMessage就 返回所有可得到的消息 。 最后一个参数可以是PM_NOREMOVE 或者 PM_REMOVE,表示消息信息是否应该从 消息队列 中删除。 函数获取之后将删除 消息队列 中的除  WM_PAINT 消息之外的其他消息,至于 WM_PAINT 则只有在其处理之后才被删除((((   从队列中删除WM_PAINT消息的情况是当显示区域重新变得有效的时候, 用ValidateRect和ValidateRgn或者BeginPaint和EndPaint来完成   ))))。 WaitMessage 原型如下:
BOOL WaitMessage();
当一个应用程序无事可做时,该函数就将 控制权交给另外的应用程序 ,同时 将该应用程序挂起 ,直到一个新的消息被放入应用程序的队列之中才返回。 消息的处理 接下来我们谈一下消息的处理,首先我们来看一下VC中的消息泵:
while(GetMessage(&msg, NULL, 0, 0)){if(!TranslateAccelerator(msg.hWnd, hAccelTable, &msg)){TranslateMessage(&msg);DispatchMessage(&msg);}}
首先,GetMessage从进程的主线程的消息队列中获取一个消息并将它复制到MSG结构,如果队列中没有消息,则 GetMessage 函数将等待一个消息的到来以后才返回。如果你将一个窗口句柄作为第二个参数传入GetMessage,那么 只有指定窗口的的消息 可以从 队列 中获得。GetMessage也可以从 消息队列 中过滤消息 只接受消息队列中落在范围内的消息 。这时候就要利用 GetMessage/PeekMessage指定一个消息过滤器 。这个过滤器是一个 消息标识符的范围 或者是 一个窗体句柄 ,或者两者同时指定。当应用程序要查找一个后入 消息队列 的消息是很有用。 WM_KEYFIRST  和  WM_KEYLAST  常量用于接受所有的键盘消息。  WM_MOUSEFIRST  和  WM_MOUSELAST  常量用于接受所有的鼠标消息。 然后TranslateAccelerator判断该消息 是不是一个按键消息并且是一个加速键消息 ,如果是,则该函数将把几个按键消息转换成一个 加速键消息 传递给窗口的 回调函数 。处理了加速键之后,函数TranslateMessage将把两个按键消息 WM_KEYDOWNWM_KEYUP  转换成一个 WM_CHAR (该消息的wParam附加参数包含了字符的ASCII码) ,不过需要注意的是,消息 WM_KEYDOWN,WM_KEYUP 仍然将传递给窗口的 回调函数 。 注意,TranslateMessage函数并不会修改原有的消息,它只是产生新的消息并投递到消息队列中。 处理完之后,DispatchMessage函数将把此消息发送给 该消息指定的窗口中已设定的回调函数 。 DispatchMessage实际上是将消息回传给操作系统,由操作系统调用窗口过程函数对消息进行处理(响应)。 如果消息是WM_QUIT,则  GetMessage返回0 ,从而 退出循环体 。应用程序可以使用 PostQuitMessage 来结束自己的 消息循环 。通常在主窗口的 WM_DESTROY消息中调用。 下面我们举一个常见的小例子来说明这个消息泵的运用:
if (::PeekMessage(&msg, m_hWnd, WM_KEYFIRST,WM_KEYLAST, PM_REMOVE)){if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE)...}
这里我们接受所有的键盘消息,所以就用WM_KEYFIRST 和 WM_KEYLAST作为参数。 所以这段小代码就是判断是否按下了Esc键,如果是就进行处理。
来源: <=3G70ACK3LdHRBbRrPu70I4EtlQCv1Fqd1Ig5krPY1JgOIMaku6zaedHjfu-Ley0MbHO1gKpHZUqlhDSRDbD_ya>  

 

本文标签: PostMessage SendMessage GetMessage PeekMessage TranslateMessage