消息機制

消息機制

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)用程序處理它們的消息浑塞。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市政己,隨后出現(xiàn)的幾起案子酌壕,更是在濱河造成了極大的恐慌,老刑警劉巖歇由,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卵牍,死亡現(xiàn)場離奇詭異,居然都是意外死亡沦泌,警方通過查閱死者的電腦和手機糊昙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谢谦,“玉大人释牺,你說我怎么就攤上這事』赝欤” “怎么了没咙?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長千劈。 經(jīng)常有香客問我祭刚,道長,這世上最難降的妖魔是什么队塘? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任袁梗,我火速辦了婚禮,結(jié)果婚禮上憔古,老公的妹妹穿的比我還像新娘遮怜。我一直安慰自己,他們只是感情好鸿市,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布锯梁。 她就那樣靜靜地躺著,像睡著了一般焰情。 火紅的嫁衣襯著肌膚如雪陌凳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天内舟,我揣著相機與錄音合敦,去河邊找鬼。 笑死验游,一個胖子當著我的面吹牛充岛,可吹牛的內(nèi)容都是我干的保檐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼崔梗,長吁一口氣:“原來是場噩夢啊……” “哼夜只!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蒜魄,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤扔亥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后谈为,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體旅挤,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年伞鲫,在試婚紗的時候發(fā)現(xiàn)自己被綠了谦铃。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡榔昔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瘪菌,到底是詐尸還是另有隱情撒会,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布师妙,位于F島的核電站诵肛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏默穴。R本人自食惡果不足惜怔檩,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蓄诽。 院中可真熱鬧薛训,春花似錦、人聲如沸仑氛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锯岖。三九已至介袜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間出吹,已是汗流浹背遇伞。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留捶牢,地道東北人鸠珠。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓巍耗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親跳芳。 傳聞我的和親對象是個殘疾皇子芍锦,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容