Windows的應用程序通常包含窗口(Window),它主要爲用戶提供一種可視化的交互方式(窗口是由線程(Thread)建立的).Windows 系統經過消息機制來讓系統和用戶進行交互,用戶經過觸發事件來觸發消息,消息(Message)被髮送,保存,處理,一個線程會維護本身的一套消息隊列(Message Queue)[僅當線程有對應的建立窗口和處理窗口消息時候],在發生輸入事件以後,Windows 系統將事件轉換爲一個消息並將消息放入程序的消息隊列中.程序經過執行一塊稱之爲「消息循環」的程序代碼從消息隊列中取出消息並調用窗體的回調函數處理消息,這樣不只保持線程間的獨佔性.並且隊列的以先進先出方式處理消息來實現異步通訊.windows
可是通常來講不是全部的消息都是須要程序處理的.而是針對其中某些特定的消息進行處理.即程序只關心本身想關心的問題而不會多去處理其餘沒必要要的信息.可是系統並不會知道什麼是程序所關心的消息,什麼是程序不關心的消息,因此它會把全部的消息都發送給程序.那麼程序便要從中塞選出本身想要處理的消息,而後把本身不想理會的消息過濾給系統,讓系統去幫助處理這些不須要的消息(即系統提供的默認的窗口過程函數 DefWindowProc).那麼通常程序的窗體過程具體流程以下:異步
上面能夠看出窗體能夠接收和處理消息的特性.然而控件其實也都是窗口.可是每一個控件卻不必定都具備接收和處理消息的功能.由於在系統中只有具備句柄(一個系統自動維護的32位的數值,是做爲系統對象的簡單的惟一性的標識)的窗口才具備處理消息的特性.由於只有具備句柄的窗口才能獨立存在做爲一窗體存在.做爲其餘控件的容器.而沒有句柄的控件,如Label,是不能獨立存在的,只能做爲窗口控件的子控件,它不能繪製自身,只能依靠父窗體將它繪製來.ide
消息由一個叫MSG的結構體定義,包括窗口句柄(HWND),消息ID(UINT),參數(WPARAM, LPARAM)等等:函數
1 struct MSG
2 {
3 HWND hwnd;
4 UINT message;
5 WPARAM wParam;
6 LPARAM lParam;
7 DWORD time;
8 POINT pt;
9 };
spa
通常來講消息可以被分爲「隊列化的」和「非隊列化的」.操作系統
系統隊列線程
當操做系統啓動並初始化時,線程Raw Input Thread(RIT)就會啓動,並創系統硬件輸入隊列(System Hardware Input Queue)(SHIQ). 對於外部的硬件事件(鼠標或者鍵盤),硬件驅動會將事件轉換成消息,並存放到SHIQ中,而RIT線程就專門負責處理SHIQ中的消息,把消息分發到對應線程的消息隊列裏面.
線程隊列翻譯
而對於線程來講,每一個線程能夠擁有本身的消息隊列,它和線程一一對應.在線程剛建立時,消息隊列並不會被建立,而是當GDI的函數調用發生時,Windows系統才認爲有必要爲線程建立消息隊列.系統會爲其維護一個THREADINFO結構. 消息隊列包含在一個叫THREADINFO的結構中,有四個隊列: * Sent Message Queue 發送消息隊列 \[該隊列保存其餘程序經過SendMessage給該線程發送的消息\] * Posted Message Queue 登記消息隊列 \[該隊列保存其餘隊列經過PostMessage給該線程發送的消息\] * Visualized Input Queue 輸入消息隊列 \[保存系統隊列分發過來的消息,好比鼠標或者鍵盤的消息\] * Reply Message Queue 響應消息隊列 \[保存向窗體發送消息後的結果,好比sendMessage操做結束後,接收消息方會發送一個Reply消息給發送方的Reply隊列中,以喚醒發送隊列\]
THREADINFO結構體定義以下圖所示:
消息能夠由Windows系統發送,也能夠由應用程序自己;能夠向線程內發送,也能夠跨線程.主要是看發送函數的調用者.設計
系統向窗口發送的消息一般包含3個參數,分別是:指針
用戶在操做程序時對電腦的操做這個事件將會被系統捕獲到,而後把這個事件翻譯成一個消息而且把消息投遞到對應的消息隊列中.而程序發現本身的消息隊列中具備消息時它便會從本身的消息隊列中取出消息並處理消息.直至消息隊列爲空爲止.
Windows消息控制中心通常是三層結構,其頂端就是Windows內核.Windows內核維護着一個消息隊列,第二級控制中心從這個消息隊列中獲取屬於本身管轄的消息,後作出處理,有些消息直接處理掉,有些還要發送給下一級窗體(Window)或控件(Control).第二級控制中心通常是各Windows應用程序的Application對象.第三級控制中心就是Windows窗體對象,每個窗體都有一個默認的窗體過程,這個過程負責處理各類接收到的消息.
首先咱們要了解 windows 系統下程序是以消息爲基礎,事件驅動之.首先用戶出發事件,而後系統把事件轉換爲對應的消息,而後把消息投遞到消息隊列中.應用程序經過消息循環得到消息,而後把消息轉交個系統,有系統再把消息交給對應的窗口回調函數(系統經過以註冊的窗口類結構中的一個指向回調函數指針的成員找到窗體的回調函數,而這個窗體結構體是在窗體建立過程當中設計窗體類時候經過定義一個 WNDCLASS 結構體設計窗體基本屬性是定義的),經過窗口回調函數來處理消息,處理消息結束後,應用回調函數把權限在交還給系統而後,系統在執行權限交給應用程序.程序繼續從消息隊列中取出消息並按上述方法去處理消息之.流程以下: