最近在看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);