PostMessage和PostThreadMessage区别

来源:互联网 发布:java递归求n的阶乘 编辑:程序博客网 时间:2024/05/18 22:42



消息队列是属于线程的,Post消息就是把消息放到目标线程的消息队列中。

这两者的区别在于:

PostMessage 通过指定目标窗口句柄来确定目标线程,通常情况下由窗口过程来处理消息;

PostThreadMessage 直接指定目标线程ID来确定目标线程,没有目标窗口,只能在消息循环中直接根据消息类型做相应的处理。

在程序设计的选择方面,如果是UI线程,则应使用PostMessage;如果是工作线程,则应使用PostThreadMessage,不要为了接收消息而创建窗口。



PostThreadMessage是一个线程体发送一个消息到指定的线程ID

      接受PostThreadMessage的线程必须已经有了一个message queue,否则调用PostThreadMessage会失败。因为此原因使用GetLastError会得到错误码为1444,这种情况经常出现,解决方法有如下两种:

1.         调用PostThreadMessage,如果失败,就Sleep一段时间再次调用PostThreadMessage直到调用成功;

2.         创建一个Event对象,让PostThreadMessage等待接受的线程创建一个message queue。可以通过调用PeekMessage强制系统创建一个message queue。示例代码如下:


#include <windows.h>#include <cstdio>#include <process.h>#define MY_MSG WM_USER+100const int MAX_INFO_SIZE = 20;HANDLE hStartEvent; // thread start event// thread functionunsigned __stdcall fun(void *param){printf("thread fun start使用PostThreadMessage在Win32线程间传递消息\n");MSG msg;PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);if(!SetEvent(hStartEvent)) //set thread start event {printf("set start event failed,errno:%d\n",::GetLastError());return 1;}while(true){if(GetMessage(&msg,0,0,0)) //get msg from message queue{switch(msg.message){case MY_MSG:char * pInfo = (char *)msg.wParam;printf("recv %s\n",pInfo);delete[] pInfo;break;}}};return 0;}int main(){HANDLE hThread;unsigned nThreadID;hStartEvent = ::CreateEvent(0,FALSE,FALSE,0); //create thread start eventif(hStartEvent == 0){printf("create start event failed,errno:%d\n",::GetLastError());return 1;}//start threadhThread = (HANDLE)_beginthreadex( NULL, 0, &fun, NULL, 0, &nThreadID );if(hThread == 0){printf("start thread failed,errno:%d\n",::GetLastError());CloseHandle(hStartEvent);return 1;}//wait thread start event to avoid PostThreadMessage return errno:1444::WaitForSingleObject(hStartEvent,INFINITE);CloseHandle(hStartEvent);int count = 0;while(true){char* pInfo = new char[MAX_INFO_SIZE]; //create dynamic msgsprintf(pInfo,"msg_%d",++count);if(!PostThreadMessage(nThreadID,MY_MSG,(WPARAM)pInfo,0))//post thread msg{printf("post message failed,errno:%d\n",::GetLastError());delete[] pInfo;}::Sleep(1000);}CloseHandle(hThread);return 0;}


原创粉丝点击