PostMessage和PostThreadMessage区别



消息队列是属于线程的,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+100
const int MAX_INFO_SIZE = 20;

HANDLE hStartEvent; // thread start event

// thread function
unsigned __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 event
	if(hStartEvent == 0)
	{
		printf("create start event failed,errno:%d\n",::GetLastError());
		return 1;
	}

	//start thread
	hThread = (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 msg
		sprintf(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;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值