详谈Windows消息循环机制
一直對windows消息循環(huán)不太清楚,今天做個詳細(xì)的總結(jié),有說錯的地方,請務(wù)必指出。
用VS2017新建一個win32 Application的默認(rèn)代碼如下:
這里有幾個概念,容易混淆:
1.系統(tǒng):
特指windows操作系統(tǒng)
2.應(yīng)用程序:
指一個程序,比如QQ,或者酷狗之類的都算一個應(yīng)用程序
3.窗口:
每個應(yīng)用程序都可以擁有窗口,而且可以有多個,但一般會有一個主窗口。例如QQ的主窗口,但是QQ也有很多類似于設(shè)置窗口的子窗口,這些窗口都屬于QQ應(yīng)用程序。
4.消息:
window系統(tǒng)定義了很多種消息,例如,單擊鼠標(biāo)、改變窗口尺寸、按下鍵盤,這些操作都會使Windows發(fā)送一個消息給應(yīng)用程序。消息本身是作為一個記錄傳遞給應(yīng)用程序的,這個記錄中包含了消息的類型以及其他信息
5.消息循環(huán):
window系統(tǒng)的一種消息機制
6.消息隊列:
是屬于線程的,是windows系統(tǒng)為線程創(chuàng)建并維護(hù)的一個隊列,用于存放各類消息。系統(tǒng)自身維護(hù)一個系統(tǒng)消息隊列,然后還為每個GUI線程線程維護(hù)一個線程專門消息隊列。
7.線程:
每個線程默認(rèn)是沒有消息隊列的,線程只有在第一次調(diào)用用戶接口時(比如創(chuàng)建窗口,或者是操作UI元素時),系統(tǒng)才為其創(chuàng)建消息隊列。一個應(yīng)用程序可以有多個線程,但只能有一個UI線程,默認(rèn)為主線程,其他子線程是無法操作UI并創(chuàng)建UI元素的。這是windows規(guī)定的
windows消息循環(huán)的詳細(xì)過程:
1.我們創(chuàng)建完win32應(yīng)用程序,當(dāng)用戶通過對鼠標(biāo),鍵盤操作應(yīng)用程序時,由于Windows一直監(jiān)控著I/O設(shè)備,該事件首先會被轉(zhuǎn)化成消息,由windows系統(tǒng)捕獲,存放于系統(tǒng)消息隊列。
2.Windows系統(tǒng)知道該消息應(yīng)由哪個應(yīng)用程序處理,然后拷貝到相應(yīng)的應(yīng)用程序消息隊列。同時將該消息從系統(tǒng)消息隊列中刪除。
3.應(yīng)用程序的消息循環(huán)不斷在執(zhí)行,此時,調(diào)用GetMessage()從消息隊列中查找消息,發(fā)現(xiàn)了該消息,GetMessage()將返回一個正值,并獲取到了該消息Msg;PS:如果消息隊列為空,程序?qū)⑼V箞?zhí)行并等待(程序阻塞)。
4. 然后取出消息(Msg)并將其傳遞給TranslateMessage()函數(shù),這個函數(shù)做一些額外的處理:將虛擬鍵值信息轉(zhuǎn)換為字符信息。這一步實際上是可選的,但有些地方需要用到這一步。
5. 上面的步驟執(zhí)行完后,將消息MSG傳遞給DispatchMessage()函數(shù)。DispatchMessage()函數(shù)將消息再給windows系統(tǒng),由windows系統(tǒng)找到目標(biāo)窗口并分發(fā)給該窗口,調(diào)用消息對應(yīng)的窗口過程函數(shù),既窗口的WinPro函數(shù),讓W(xué)inPro函數(shù)處理。WinPro函數(shù)可以允許我們對不同的消息做特定的處理,若不處理的話,則會調(diào)用DefWindowProc函數(shù),做默認(rèn)處理,所以為什么默認(rèn)代碼中WinPro的類型是CallBack(回調(diào)),因為不是我們主動調(diào)用的,是系統(tǒng)回調(diào)的
6. 一旦一個消息處理完成,窗口過程WinPro函數(shù)返回,DispatchMessage()函數(shù)返回,應(yīng)用程序的消息循環(huán)繼續(xù)while循環(huán),Window系統(tǒng)繼續(xù)監(jiān)控各類消息,重復(fù)上述步驟
總結(jié)
以上是生活随笔為你收集整理的详谈Windows消息循环机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深入理解Windows消息循环
- 下一篇: 《 Spring 实战 》(第4版) 读