Windows消息映射及消息发送(SendMess、PostMess)实现

  最近在看linux系统书籍看到消息调度方面,便动手封装一个类似MFC简易的消息发送框架(参考实例,没有窗口句柄)。

  关于框架设计的几点介绍:
    1.设计采用了自动释放消息节点方式(增加虚析构函数在内部做相关释放判断,即使用完不释放节点也没关系);
    2.设计采用了双向链表方式做消息绑定节点(为了方便起见,没有采用环形双向链表);
    3.SendMess采用直接调用消息函数方式;
    4.PostMess按照我的想法多个线程同时发送一个消息,那么这个消息调用次数进行叠加一直调用完成为止。

  函数定义如下:

//第一个参数 消息ID,第二个参数 消息函数
#define  Test_AddOnMess(id,pthis)   AddMess(id,*pthis);//消息映射宏
void AddMess(int id,LRESULT (* pn)(WPARAM,LPARAM));

LRESULT TestMess(WPARAM wp,LPARAM lp);//测试消息函数
//第一个参数 消息ID,第二个参数 指定附加的消息,第三个参数 指定附加的消息
int Test_SendMess(UINT mess,WPARAM wp,LPARAM lp);//SendMess函数
//第一个参数 消息ID,第二个参数 指定附加的消息,第三个参数 指定附加的消息
int Test_PostMess(UINT mess,WPARAM wp,LPARAM lp);//PostMess函数

typedef struct Test_Mess //消息数据结构体
{
	int id;//消息ID
	volatile int MessRun;//运行状态
	volatile int messNum;//运行次数
	LRESULT (* pn)(WPARAM wp,LPARAM lp);//消息函数
	Test_Mess *prev,*next; //链表节点
}*pTest_Mess;

typedef struct Test_Run//消息执行结构体
{
	pTest_Mess test_Mess,test_Messhead;
	Test_Run()
	{
		test_Mess = test_Messhead = 0;
	}
	virtual ~Test_Run()
	{
		while (0 != test_Messhead)
		{
			pTest_Mess dele;
			dele = test_Messhead->next;
			while (0 != test_Messhead->MessRun)//如果消息还没执行完成,等待执行完成为止
				;
			delete test_Messhead;
			test_Messhead = dele;
		}
	}
};
Test_Run testrun;

  代码实现如下:

void AddMess(int id,LRESULT (* pn)(WPARAM,LPARAM))//消息绑定函数实现
{
	if (0 > id || 0 == pn)
	{
		return ;
	}
	testrun.test_Mess = testrun.test_Messhead;
	if (0 != testrun.test_Mess)//检查是否ID号相同
	{
		while (id != testrun.test_Mess->id && 0 != testrun.test_Mess->next)
			testrun.test_Mess = testrun.test_Mess->next;
		if (id == testrun.test_Mess->id)
		{
			return ;
		}
	}
	if (0 == testrun.test_Mess)
	{
		testrun.test_Mess = new Test_Mess;
		testrun.test_Mess->next = 0;
		testrun.test_Mess->prev = 0;
		testrun.test_Messhead = testrun.test_Mess;
	}
	else
	{
		while (0 != testrun.test_Mess->next)
			testrun.test_Mess = testrun.test_Mess->next;
		testrun.test_Mess->next = new Test_Mess;
		testrun.test_Mess->next->next = 0;
		testrun.test_Mess->next->prev = testrun.test_Mess;
	}
	while (0 != testrun.test_Mess->next)
		testrun.test_Mess = testrun.test_Mess->next;
	testrun.test_Mess->id = id;
	testrun.test_Mess->MessRun = 0;
	testrun.test_Mess->pn = pn;
	testrun.test_Mess->messNum = 0;
}


LRESULT TestMess(WPARAM wp,LPARAM lp)//测试消息函数实现
{
	return 0;
}

int Test_SendMess(UINT mess,WPARAM wp,LPARAM lp)//SendMess函数实现
{
	pTest_Mess test_mess = testrun.test_Messhead;
	if (0 == test_mess)
	{
		return -2;
	}
	while (mess != test_mess->id && 0 != test_mess->next)
		test_mess = test_mess->next;
	if (mess != test_mess->id)
	{
		return -1;
	}
	test_mess->MessRun = 1;//这个参数的作用类似于锁,如果不执行完成 那么就达不到析构条件
	//因为是Send方式直接启动
	test_mess->pn(wp,lp);
	test_mess->MessRun = 0;
	return mess;//返回消息ID表示成功
}


int Test_PostMess(UINT mess,WPARAM wp,LPARAM lp)//PostMess函数实现
{
	pTest_Mess test_mess = testrun.test_Messhead;
	if (0 == test_mess)
	{
		return -2;
	}
	while (mess != test_mess->id && 0 != test_mess->next)
		test_mess = test_mess->next;
	if (mess != test_mess->id)
	{
		return -1;
	}
	test_mess->MessRun = 1;
	test_mess->messNum++;//post的设计为多个线程同时发送一个消息,那么消息进行叠加一直执行完成所有消息为止
	while (0 < test_mess->messNum)
	{
		test_mess->pn(wp,lp);
		test_mess->messNum--;
	}
	test_mess->MessRun = 0;
	return mess;
}

  使用方式:

Test_AddOnMess(1,TestMess);//类似于MFC ON_Message 宏
Test_AddOnMess(2,TestMess);
Test_AddOnMess(3,TestMess);

Test_SendMess(2,2,3);
Test_PostMess(3,5,6);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坤昱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值