Windows訊息機制-摘要&理解

來源:互聯網
上載者:User

 

Windows系統是一個訊息驅動的系統

1.訊息是一個結構體類型的記錄,大致包括:hwnd-視窗控制代碼、uint-訊息常量標識符、wparam-32位訊息特定附加資訊、lparam32位訊息特定附加資訊、dword-訊息建立時的時間、tpoint-訊息建立時滑鼠座標

2.訊息佇列,Windows能夠為所有的應用程式維護一個訊息佇列,應用程式必須從訊息佇列中擷取訊息,然後指派給某個視窗。(應用程式主動去訊息佇列裡擷取?)(訊息佇列可以有多個?)(每個線程都有一個訊息佇列)

3.訊息迴圈,通過這個迴圈機制應用程式從訊息佇列中檢索訊息,再把它指派給適當的視窗,然後繼續從訊息佇列中檢索下一條訊息,再指派給適當的視窗,一次進行。(應用程式主動參與迴圈尋找訊息?相當於一個 while(true)無限迴圈?)(每個應用程式都有自己的訊息迴圈,在迴圈中得到屬於自己的訊息,在沒有訊息時訊息迴圈就將控制權交給系統)
訊息迴圈是應用程式能夠持續存在的根本原因。如果迴圈退出,則應用程式就結束了。

4.視窗過程,每個視窗都有一個視窗過程來接收傳遞給視窗的訊息,它的任務就是擷取訊息然後響應它,視窗過程是一個回呼函數;處理了一個訊息後,它通常要返回一個值給Windows。(一個應用程式可以有多個視窗)(回呼函數是程式中的一種函數,它是由Windows或外部模組調用的)

一個訊息從產生到被一個視窗響應,有五個步驟:

1.系統中發生了某個事件。(DataReceive事件如何被觸發?)

2.Windows把這個事件翻譯為訊息,然後把它放到訊息佇列中。

3.應用程式從訊息佇列中接收到這個訊息,把它存放在TMsg記錄中。

4.應用程式把訊息傳遞給一個適當的視窗的視窗過程。(視窗過程是不是一個系統函數)

5.視窗過程響應這個訊息並進行處理。

步驟3,4構成了應用程式的訊息迴圈。訊息迴圈往往是Windows應用程式的核心,因為訊息迴圈使一個應用程式能夠響應外部的事件。訊息迴圈的任務就是從訊息佇列中檢索訊息,然後把訊息傳遞給適當的視窗。如果訊息佇列中沒有訊息,Windows就允許其他應用程式處理它們的訊息。

Windows作業系統最大的特點就是其圖形化的操作介面,其圖形化介面是建立在其訊息處理機制這個基礎之上的。

Windows訊息控制中心就像是一顆心臟,訊息就像是血液。

Windows訊息控制中心一般是三層結構,其頂端就是Windows核心。Windows核心維護著一個訊息佇列。第二級控制中心一般是各Windows應用程式的Application對象,從這個訊息佇列中擷取屬於自己管轄的訊息,後做出處理,有些訊息直接處理掉,有些還要發送給下一級表單(Window)或控制項(Control)。第三級控制中心就是Windows表單對象,每一個表單都有一個預設的表單過程,這個過程負責處理各種接收到的訊息。

表單:包括視窗,以及有控制代碼的控制項;control指控制項,控制項本身也可能是一個window,也可能不是;Application即應用程式,應用程式也可能不會用到Windows訊息機制。

1.標準Windows訊息,這種訊息以WM_打頭。

2.通知訊息,是針對標準Windows控制項的訊息。(包括:按鈕(Button)、組合框(ComboBox)、編輯框(TextBox)、ListView控制項、Treeview控制項、工具條(Toolbar)、菜單(Menu)等。每種訊息以不同的字串打頭。

3.自訂訊息,編程人員還可以自訂訊息。

只有具有控制代碼(handle)的控制項才能做到接收訊息,轉寄訊息和繪製自身。有控制代碼的控制項本質上都是一個表單(window),它們可以獨立存在,可以作為其它控制項的容器,而沒有控制代碼的控制項,如Label,是不能獨立存在的,只能作為視窗控制項的子控制項,它不能繪製自身,只能依靠父表單將它繪製來。

控制代碼的本質是一個系統自動維護的32位的數值,在整個作業系統的任一時刻,這個數值是唯一的。但該控制代碼代表的表單釋放後,控制代碼也會被釋放,這個數值又可能被其它表單使用。也就是說,控制代碼的數值是動態,它本身只是一個唯一性標識,作業系統通過控制代碼來識別和尋找它所代表的對象。

然而,並非所有的控制代碼都是表單的控制代碼,Windows系統中還中很多其它類型的控制代碼,如畫布(hdc)控制代碼,畫筆控制代碼,畫刷控制代碼,應用程式控制代碼(hInstance)等。這種控制代碼是不能接收訊息的。但不管是哪種控制代碼,都是系統中對象的唯一標識。本文只討論表單控制代碼。

從訊息佇列擷取訊息:可以通過PeekMessage或GetMessage函數從Windows訊息佇列中擷取訊息。Windows儲存的訊息佇列是以線程(Thread)來分組的,也就是說每個線程都有自己的訊息佇列。

發送訊息,到指定表單一般通過以下兩個函數完成:SendMessage和PostMessage。兩個函數的區別在於:PostMessage函數只是向線程訊息佇列中添加訊息,如果添加成功,則返回True,否則返回False,訊息是否被處理,或處理的結果,就不知道了。而SendMessage則有些不同,它並不是把訊息加入到隊列裡,而是直接翻譯訊息和調用訊息處理(線程向自己發送訊息才是這樣),直到訊息處理完成後才返回。所以,如果我們希望發送的訊息立即被執行,就應該調用SendMessage。

表單過程實際上是一個回呼函數。所謂的回呼函數,實際上就是由Windows作業系統或外部程式調用的函數。回呼函數一般都有規定的參數格式,以地址方式傳遞給調用者。視窗過程中是Windows作業系統調用了,在一個視窗建立的時候,在分配表單控制代碼的時候就需要傳入回呼函數地址。那為什麼我們平時編程看不到這個回呼函數呢?這是由於我們的編程工具已經為我們產生了預設的表單過程,這個過程的要做的事情就是判斷不同的訊息類型,然後做出不同的處理。例如可以為鍵盤或滑鼠輸入建置事件等。

事件本質上是對訊息的封裝,是IDE編程環境為了簡化編程而提供的有用的工具。這個封裝是在表單過程中實現的。每種IDE封裝了許多Windows的訊息,例如:
OnActivate-WM_ACTIVATE
OnClick-WM_XBUTTONDOWN
OnCreate-WM_CREATE
OnDblClick-WM_XBUTTONDBLCLICK
OnKeyDown-WM_KEYDOWN
OnKeyPress-WM_CHAR
OnKeyUp-WIN_KEYUP
OnPaint-WM_PAINT
OnResize-WM_SIZE
OnTimer-WM_TIMER

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.