WINAPI多线程消息通讯

多线程之间可以使用WINDOWS消息机智来进行消息通讯。

一个线程原本是没有消息队列的,调用任何与消息相关的API会自动初始化线程消息队列相关的数据结构。

 

 

自定义Windows消息

#define MY_MSG  (WM_USER+1)

注:

(1)为了防止用户定义的消息ID与系统的消息ID冲突,Microsoft定义了一个宏 #define WM_USER 0X0400.

(2)小于WM_USER的ID被系统使用,大于WM_USER的ID被用户使用。

 

 

PostThreadMessage将信息发送到指定线程

BOOL PostThreadMessage(DWORD idThread,

                                            UINT       Msg,

                                            WPARAM  wParam,

                                            LPARAM    lParam);

目标线程通过GetMessage()方法来接收消息。

 

参数:

idThread:    接收消息的线程id

Msg:           指定被寄送的消息

wParam:     指定附加的消息特定的信息

lParam:       指定附加的消息特定的信息

 

返回值:

成功:返回非零

失败:返回零

调用GetLastError返回1444可能是线程不存在消息列队 

 

 

GetMessage从消息列队中获取消息

BOOL GetMessage(LPMSG lpMsg.

                                HWND hWnd,

                                UINT     wMsgFilterMin,

                                UINT     sMsgFilterMax);

目标线程通过GetMessage()方法来接收消息,若无消息则阻塞。

参数:

lpMsg:                 接收消息的线程id

hWnd:               取得消息的窗口的句柄,当NULL 时获取所属线程的消息            

wMsgFilterMin: 指定被检索的最小消息值的整数

sMsgFilterMax: 指定被检索的最大消息值的整数

 

返回值:

(1)如果函数取的时WM_QUIT之外的其他消息,返回非零值。否则返回值是零。

(2)错误返回-1。

(3)调用GetLastError函数获取错误。

 

 

 

PeekMessage窥探消息队列中的消息

BOOL PeekMessage(LPMSG lpMsg,

                                  HWND hWnd,

                                  UINT    wMSGfilterMin,

                                  UINT    wMsgFilterMax,

                                  UINT    wRemoveMsg);

返回:

(1)如果消息可得到,返回非零值。

(2)如果消息未得到,返回零。

 

参数:

lpMsg:接收消息的线程id。

hWnd:获得消息的窗口的句柄,NULL时获取所属线程的消息。

wMSGfilterMin:指定被检索的最小消息值的整数。

wMsgFilterMax:指定被检索的最大消息值的整数。

wRemoveMsg:此参数可取下列值之一:

           (1)PM_NOREMOVE  获取消息后不从队列里删除。

           (2)PM_REMOVE        获取消息后从列队里删除。

           (3)PM_NOYIELD       使系统不释放等待调用程序空闲的线程

           (4)可将PM_NOYIELD随意组合到PM_NOREMOVE/PM_REMOVE.

 

 

 

                                                        PeekMessage   /  GetMessage的区别

 

函数

是否立即返回

返回值

处理

GetMessage

若取不到消息,则线程就会被操作系统挂起,阻塞。

有消息:TRUE

无消息:FALSE

消息被取出后,就从消息队列中将其删除。

PeekMessage

立即返回

有消息:(不为WM_QUIT)返回TRUE。

WM_QUIT:返回FALSE.

无消息:不返回

PM_REMOVE:消息被取出并从消息队列中删除。

PM_NOREMOVE:窥探,不删除。

 

 

#include<windows.h>
#include<stdio.h>

#define MY_MSG WM_USER+1

DWORD WINAPI threadFun1(LPVOID paramer);
DWORD WINAPI threadFun2(LPVOID paramer);
int main()
{
	DWORD threadID = 0;
	HANDLE hThread1 = CreateThread(NULL, 0, threadFun1, NULL, 0, &threadID);
	HANDLE hThread2 = CreateThread(NULL, 0, threadFun2, (LPVOID)threadID, 0, NULL);
	HANDLE Arry[] = { hThread1,hThread2 };
	WaitForMultipleObjects(2, Arry, TRUE, INFINITE);
	printf("End!\n");
	return 0;
}

DWORD WINAPI threadFun1(LPVOID paramer)
{
	MSG msg;

		//while (GetMessage(&msg, NULL, 0, 0))
		//{
		//	switch (msg.message)
		//	{
		//	case MY_MSG:printf("接收消息为:%d\n", msg.wParam); break;
		//	}
		//}
		//printf("接收到退出消息,退出!\n"); return 0;

	//PeekMessage
	while (true)
	{
		while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			switch (msg.message)
			{
			case MY_MSG:printf("接收消息为:%d\n", msg.wParam); break;
			case WM_QUIT:printf("接收到退出消息,退出!\n"); return 0;
			}
		}
	}
	return 0;
}

DWORD WINAPI threadFun2(LPVOID paramer)
{
	DWORD threadID = (DWORD)paramer;
	int i = 1;
	while (true)
	{
		if (i <= 10)
			PostThreadMessage(threadID, MY_MSG, i, NULL);
		else
		{
			PostThreadMessage(threadID, WM_QUIT, NULL, NULL);
			break;
		}
		i++;
		Sleep(500);
	}
	return 0;
}

 

以上内容为学习笔记。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值