消息機制
Windows消息系統(tǒng)是由以下三部分構(gòu)成的:
1、消息隊列
2饥伊、消息循環(huán)
3象浑、窗口過程
關(guān)于消息、窗口過程
一個消息由一個消息名稱(UINT)琅豆,和兩個參數(shù)(WPARAM愉豺,LPARAM)組成。當用戶進行了輸入或是窗口的狀態(tài)發(fā)生改變時系統(tǒng)都會發(fā)送消息到某一個窗口茫因。例如當菜單轉(zhuǎn)中之后會有WM_COMMAND消息發(fā)送蚪拦,WPARAM的高字中(HIWORD(wParam))是命令的ID號,對菜單來講就是菜單ID冻押。當然用戶也可以定義自己的消息名稱驰贷,也可以利用自定義消息來發(fā)送通知和傳送數(shù)據(jù)。
一個消息必須由一個窗口接收洛巢。在窗口的過程(WNDPROC)中可以對消息進行分析括袒,對自己需要的消息進行處理。例如你希望對菜單選擇進行處理那么你可以定義對WM_COMMAND進行處理的代碼稿茉,如果希望在窗口中進行圖形輸出就必須對WM_PAINT進行處理箱熬。
M$為窗口編寫了默認的窗口過程类垦,這個窗口過程將負責處理那些你不處理消息。正因為有了這個默認窗口過程我們才可以利用Windows的窗口進行開發(fā)而不必過多關(guān)注窗口各種消息的處理城须。例如窗口在被拖動時會有很多消息發(fā)送,而我們都可以不予理睬讓系統(tǒng)自己去處理米苹。
消息分類
消息能夠被分為「隊列化的」和「非隊列化的」糕伐。
隊列化的消息是由Windows放入程序消息隊列中的。在程序的消息循環(huán)中蘸嘶,重新傳回并分配給窗口消息處理程序良瞧。非隊列化的消息在Windows呼叫窗口時直接送給窗口消息處理程序。也就是說训唱,隊列化的消息被「發(fā)送」給消息隊列褥蚯,而非隊列化的消息則「發(fā)送」給窗口消息處理程序。任何情況下况增,窗口消息處理程序都將獲得窗口所有的消息--包括隊列化的和非隊列化的赞庶。窗口消息處理程序是窗口的「消息中心」。隊列化消息基本上是使用者輸入的結(jié)果澳骤,以擊鍵(如WM_KEYDOWN和WM_KEYUP消息)歧强、擊鍵產(chǎn)生的字符(WM_CHAR)、鼠標移動(WM_MOUSEMOVE)和鼠標按鈕(WM_LBUTTONDOWN)的形式給出为肮。隊列化消息還包含時鐘消息(WM_TIMER)摊册、更新消息(WM_PAINT)和退出消息(WM_QUIT)。
非隊列化消息則是其它消息颊艳。在許多情況下茅特,非隊列化消息來自呼叫特定的Windows函數(shù)。例如棋枕,當WinMain呼叫CreateWindow時白修,Windows將建立窗口并在處理中給窗口消息處理程序發(fā)送一個WM_CREATE消息。當WinMain呼叫ShowWindow時戒悠,Windows將給窗口消息處理程序發(fā)送WM_SIZE和WM_SHOWWINDOW消息熬荆。當WinMain呼叫UpdateWindow時,Windows將給窗口消息處理程序發(fā)送WM_PAINT消息绸狐。鍵盤或鼠標輸入時發(fā)出的隊列化消息信號卤恳,也能在非隊列化消息中出現(xiàn)。例如寒矿,用鍵盤或鼠標選擇了一個菜單項時突琳,鍵盤或鼠標消息就是隊列化的,而說明菜單項已選中的WM_COMMAND消息則可能就是非隊列化的符相。
窗口過程處理消息偽代碼
LONG yourWndProc(HWND hWnd,UINT uMessageType,WPARAM wP,LPARAM)
{
switch(uMessageType)
{//使用SWITCH語句將各種消息分開
case(WM_PAINT):
doYourWindow(...);//在窗口需要重新繪制時進行輸出
break;
case(WM_LBUTTONDOWN):
doYourWork(...);//在鼠標左鍵被按下時進行處理
break;
default:
callDefaultWndProc(...);//對于其它情況就讓系統(tǒng)自己處理
break;
}
}
關(guān)于句柄
在windows中拆融,句柄是和對象一一對應(yīng)的32位無符號整數(shù)值蠢琳。對象可以映射到唯一的句柄,句柄也可以映射到唯一的對象镜豹。句柄是一種內(nèi)部代碼傲须,通過它能引用受系統(tǒng)控制的特殊元素,如窗口趟脂、位圖泰讽、圖標、內(nèi)存塊昔期、光標已卸、字體、菜單等硼一。
在消息發(fā)送的過程中累澡,有一個很重要的東西就是窗口句柄。系統(tǒng)通過窗口句柄來在整個系統(tǒng)中唯一標識一個窗口般贼,發(fā)送一個消息時必須指定一個窗口句柄表明該消息由那個窗口接收愧哟。而每個窗口都會有自己的窗口過程,所以用戶的輸入就會被正確的處理具伍。
消息隊列
消息隊列就是一個消息的鏈表翅雏。可以把消息看作一個記錄人芽,具有特定的格式以及特定的優(yōu)先級望几。對消息隊列有寫權(quán)限的進程可以向消息隊列中按照一定的規(guī)則添加新消息;對消息隊列有讀權(quán)限的進程則可以從消息隊列中讀走消息萤厅。消息隊列是隨內(nèi)核持續(xù)的橄抹。
消息隊列(Message Queue),是分布式系統(tǒng)中重要的組件惕味,其通用的使用場景可以簡單地描述為:當不需要立即獲得結(jié)果楼誓,但是并發(fā)量又需要進行控制的時候,差不多就是需要使用消息隊列的時候名挥。
消息隊列主要解決了應(yīng)用耦合疟羹、異步處理、流量削鋒等問題禀倔。當前使用較多的消息隊列有RabbitMQ榄融、RocketMQ、ActiveMQ救湖、Kafka愧杯、ZeroMQ、MetaMq等鞋既,而部分數(shù)據(jù)庫如Redis力九、Mysql以及phxsql也可實現(xiàn)消息隊列的功能耍铜。
附:消息隊列相關(guān)介紹
使用消息隊列的十大理由:https://www.oschina.net/translate/top-10-uses-for-message-queue?cmp
消息隊列使用的四種場景介紹:https://blog.csdn.net/seven__________7/article/details/70225830
消息隊列及常見消息隊列介紹:http://baijiahao.baidu.com/s?id=1579988943735023087&wfr=spider&for=pc
再談消息隊列技術(shù):https://www.cnblogs.com/tianqing/p/7110468.html
為什么會需要消息隊列?https://www.cnblogs.com/xuyatao/p/6864109.html
消息循環(huán)
Windows是以消息驅(qū)動的操作系統(tǒng)跌前,Windows 消息提供了應(yīng)用程序與Windows系統(tǒng)之間進行通訊的手段棕兼。
Windows應(yīng)用程序是基于消息的程序設(shè)計模式,使用事件驅(qū)動編程模型舒萎,分為消息概述程储、消息結(jié)構(gòu)、消息類型臂寝。
Windows 中有一個系統(tǒng)消息隊列,對于每一個正在執(zhí)行的Windows應(yīng)用程序,系統(tǒng)為其建立一個“消息隊列”摊灭,即應(yīng)用程序隊列咆贬,用來存放該程序可能創(chuàng)建的各種窗口的消息。應(yīng)用程序中含有一段稱作“消息循環(huán)”的代碼帚呼,用來從消息隊列中檢索這些消息并把它們分發(fā)到相應(yīng)的窗口函數(shù)中掏缎。
消息循環(huán)代碼是應(yīng)用程序中主函數(shù)WinMain ( )中類似如下的程序段:
while(GetMessage(&msg,NULL,0,0))
{ //從消息隊列中取得消息
TranslateMessage(&msg); //檢索并生成字符消息WM_CHAR
DispatchMessage(&msg); //將消息發(fā)送給相應(yīng)的窗口函數(shù)
}
由此可見,所謂“消息循環(huán)”,實際是程序循環(huán)煤杀。
Windows 應(yīng)用程序創(chuàng)建的每個窗口都在系統(tǒng)核心注冊一個相應(yīng)的窗口函數(shù)眷蜈,窗口函數(shù)程序代碼形式上是一個巨大的switch 語句(見上文),用以處理由消息循環(huán)發(fā)送到該窗口的消息沈自,窗口函數(shù)由Windows 采用消息驅(qū)動的形式直接調(diào)用酌儒,而不是由應(yīng)用程序顯示調(diào)用的,窗口函數(shù)處理完消息后又將控制權(quán)返回給Windows枯途。
小結(jié)
一個消息從產(chǎn)生到被一個窗口響應(yīng)忌怎,其中有5個步驟:
1、系統(tǒng)中發(fā)生了某個事件酪夷。
2榴啸、Windows把這個事件翻譯為消息,然后把它放到消息隊列中晚岭。
3鸥印、應(yīng)用程序從消息隊列中接收到這個消息,把它存放在TMsg記錄中坦报。
4库说、應(yīng)用程序把消息傳遞給一個適當?shù)拇翱诘拇翱谶^程。
5燎竖、窗口過程響應(yīng)這個消息并進行處理璃弄。
步驟3和4構(gòu)成了應(yīng)用程序的消息循環(huán)。消息循環(huán)往往是Windows應(yīng)用程序的核心构回,因為消息循環(huán)使一個應(yīng)用程序能夠響應(yīng)外部的事件夏块。消息循環(huán)的任務(wù)就是從消息隊列中檢索消息疏咐,然后把消息傳遞給適當?shù)拇翱凇H绻㈥犃兄袥]有消息脐供,Windows就允許其他應(yīng)用程序處理它們的消息浑塞。