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