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