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;
}


Creating Windows CreateMDIWindow CreateWindow CreateWindowEx RegisterClass RegisterClassEx UnregisterClass Message Processing BroadcastSystemMessage CallNextHookEx CallWindowProc DefFrameProc DefMDIChildProc DefWindowProc DispatchMessage GetMessage GetMessageExtraInfo GetMessagePos GetMessageTime GetQueueStatus InSendMessage PeekMessage PostMessage PostQuitMessage PostThreadMessage RegisterWindowMessage ReplyMessage SendMessage SendMessageCallback SendMessageTimeout SendNotifyMessage SetMessageExtraInfo SetWindowsHookEx TranslateMessage UnhookWindowsHookEx WaitMessage Window Information AnyPopup ChildWindowFromPoint ChildWindowFromPointEx EnableWindow EnumChildWindows EnumPropsEx EnumThreadWindows EnumWindows FindWindow FindWindowEx GetClassInfoEx GetClassLong GetClassName GetClientRect GetDesktopWindow GetFocus GetForegroundWindow GetNextWindow GetParent GetProp GetTopWindow GetWindow GetWindowLong GetWindowRect GetWindowText GetWindowTextLength IsChild IsIconic IsWindow IsWindowEnabled IsWindowUnicode IsWindowVisible IsZoomed RemoveProp SetActiveWindow SetClassLong SetFocus SetForegroundWindow SetParent SetProp SetWindowLong SetWindowText WindowFromPoint Processes and Threads CreateEvent CreateMutex CreateProcess CreateSemaphore CreateThread DeleteCriticalSection DuplicateHandle EnterCriticalSection ExitProcess ExitThread GetCurrentProcess GetCurrentProcessId GetCurrentThread GetCurrentThreadId GetExitCodeProcess GetExitCodeThread GetPriorityClass GetThreadPriority GetWindowThreadProcessId InitializeCriticalSection InterlockedDecrement InterlockedExchange InterlockedIncrement LeaveCriticalSection OpenEvent OpenMutex OpenProcess OpenSemaphore PulseEvent ReleaseMutex ReleaseSemaphore ResetEvent ResumeThread SetEvent SetPr
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值