消息結(jié)構(gòu)體
typedef struct tagMSG
{
HWND hwnd; //窗口句柄蛾坯。
UINT message; //消息類型。
WPARAM wParam; //32位附加信息挂疆。
LPARAM lParam; //32位附加信息下翎。
DWORD time; //消息發(fā)送時(shí)間。
POINT pt; //消息發(fā)送時(shí)胆萧,鼠標(biāo)所在位置俐东。
} MSG;
消息隊(duì)列
消息隊(duì)列有兩種虏辫,分為系統(tǒng)消息隊(duì)列和應(yīng)用程序消息隊(duì)列。產(chǎn)生的消息首先由Windows系統(tǒng)捕獲羹唠,放在系統(tǒng)消息隊(duì)列娄昆,再拷貝到對(duì)應(yīng)的應(yīng)用程序消息隊(duì)列。
消息循環(huán)
消息循環(huán)會(huì)不斷檢索自身的消息隊(duì)列哺眯。每有一個(gè)消息扒俯,就用GetMessage()取出消息一疯。
while(GetMessage (&msg, NULL, 0, 0)) //Windows消息循環(huán)。
{
TranslateMessage(&msg); //翻譯消息互纯,如按鍵消息留潦,翻譯為WM_CHAR
DispatchMessage(&msg); //分發(fā)消息到對(duì)應(yīng)窗口
}
當(dāng)用戶運(yùn)行一個(gè)應(yīng)用程序,通過對(duì)鼠標(biāo)的點(diǎn)擊或鍵盤按鍵殖卑,產(chǎn)生一些特定事件坊萝。由于Windows一直監(jiān)控著I/O設(shè)備,該事件首先會(huì)被翻譯成消息菩鲜,由系統(tǒng)捕獲惦积,存放于系統(tǒng)消息隊(duì)列狮崩。經(jīng)分析,Windows知道該消息應(yīng)由那個(gè)應(yīng)用程序處理诽凌,則拷貝到相應(yīng)的應(yīng)用程序消息隊(duì)列坦敌。由于消息循環(huán)不斷檢索自身的消息隊(duì)列恬试,當(dāng)發(fā)現(xiàn)應(yīng)用程序消息隊(duì)列里有消息,就用GetMessage()取出消息训柴,封裝成Msg()結(jié)構(gòu)幻馁。如果該消息是由鍵盤按鍵產(chǎn)生的越锈,用TranslateMessage()翻譯為WM_CHAR消息膘滨,否則火邓,用DisPatchMessage()將取出的消息分發(fā)到相應(yīng)的應(yīng)用程序窗口,交由窗口處理程序處理躲胳。Windows為每個(gè)窗體預(yù)留了過程窗口函數(shù)纤勒,該函數(shù)是一個(gè)回掉函數(shù),由系統(tǒng)調(diào)用粹湃,應(yīng)用程序不能調(diào)用泉坐。程序員可以通過重載該函數(shù)處理我們”感興趣”的消息坚冀。對(duì)于不感興趣的消息,則由系統(tǒng)默認(rèn)的窗口過程處理程序做出處理司训。
windows消息循環(huán)的詳細(xì)過程:
- 我們創(chuàng)建完win32應(yīng)用程序液南,當(dāng)用戶通過對(duì)鼠標(biāo),鍵盤操作應(yīng)用程序時(shí)统扳,由于Windows一直監(jiān)控著I/O設(shè)備咒钟,該事件首先會(huì)被轉(zhuǎn)化成消息若未,由windows系統(tǒng)捕獲,存放于系統(tǒng)消息隊(duì)列萍嬉。
- Windows系統(tǒng)知道該消息應(yīng)由哪個(gè)應(yīng)用程序處理,然后拷貝到相應(yīng)的應(yīng)用程序消息隊(duì)列磕道。同時(shí)將該消息從系統(tǒng)消息隊(duì)列中刪除溺蕉。
- 應(yīng)用程序的消息循環(huán)不斷在執(zhí)行资柔,此時(shí)撵割,調(diào)用GetMessage()從消息隊(duì)列中查找消息,發(fā)現(xiàn)了該消息羹与,GetMessage()將返回一個(gè)正值庶灿,并獲取到了該消息Msg往踢;PS:如果消息隊(duì)列為空峻呕,程序?qū)⑼V箞?zhí)行并等待(程序阻塞)。
- 然后取出消息(Msg)并將其傳遞給TranslateMessage()函數(shù),這個(gè)函數(shù)做一些額外的處理:將虛擬鍵值信息轉(zhuǎn)換為字符信息热押。這一步實(shí)際上是可選的桶癣,但有些地方需要用到這一步鬼廓。
- 上面的步驟執(zhí)行完后致盟,將消息MSG傳遞給DispatchMessage()函數(shù)碎税。DispatchMessage()函數(shù)將消息再給windows系統(tǒng),由windows系統(tǒng)找到目標(biāo)窗口并分發(fā)給該窗口伟端,調(diào)用消息對(duì)應(yīng)的窗口過程函數(shù),既窗口的WinPro函數(shù)匪煌,讓W(xué)inPro函數(shù)處理责蝠。WinPro函數(shù)可以允許我們對(duì)不同的消息做特定的處理,若不處理的話萎庭,則會(huì)調(diào)用DefWindowProc函數(shù),做默認(rèn)處理驳规,所以為什么默認(rèn)代碼中WinPro的類型是CallBack(回調(diào)),因?yàn)椴皇俏覀冎鲃?dòng)調(diào)用的吗购,是系統(tǒng)回調(diào)的
- 一旦一個(gè)消息處理完成,窗口過程WinPro函數(shù)返回,DispatchMessage()函數(shù)返回踱启,應(yīng)用程序的消息循環(huán)繼續(xù)while循環(huán),Window系統(tǒng)繼續(xù)監(jiān)控各類消息埠偿,重復(fù)上述步驟
定時(shí)器消息
模態(tài)對(duì)話框?qū)崿F(xiàn)原理
對(duì)話框接收了應(yīng)用的消息循環(huán)胚想。
MFC 模態(tài)對(duì)話框的實(shí)現(xiàn)原理
自實(shí)現(xiàn)一個(gè)模態(tài)對(duì)話框。