早期程序使用輸入-操做-輸出的機制,整個流程徹底由程序員事先設定好。程序員
事件驅動機制是指程序按照事件發生的次序隨機執行而不是按照編程時就定義好的順序執行當某個事件發生時程序將找到相應的事件處理程序來處理事件。因此具備順序結構的編程顯然不具備事件驅動的先決條件。
面向對象程序設計當中採用的就是事件驅動機制。好比說鼠標左擊、雙擊都是具體事件,根據這些事件啓用預先設置的相應動做就是事件驅動機制。注意這些事件是隨機觸發的,並無預先決定它們的發生順序,預先設計好的是它們的處理方法(事件handler)編程
當前,事件機制是組件和交互式開發所必須的一種技術。windows
事件機制例子:當用戶輸入一個字符或者是單擊一次鼠標,一個事件就發生了。任何一個程序中的對象均可能被通知到有某事件發生,只要它實現了一些相應的接口或者是事先在一個具有事件監聽功能的對象那裏註冊好了,告訴它「有什麼事件時通知我一下」。被通知後,對象能夠作出不一樣的響應,以實現各自的功能。app
事件觸發機制相對於簡單的輪詢機制來講,優勢以下:ide
圖形用戶界面就是利用這種事件響應來實現接收用戶操做的。那麼究竟是怎麼實現的呢。當前各類語言、類庫、平臺大都會提供事件機制,至於實現方式便有不少種。函數
C#的委託事件機制很是優雅的解決了對象間通訊機制。post
首先能夠將委託delegate當作是函數指針類型的抽象:字體
public delegate void delegatesome(type1 para1, type2 para2, type3 para3, ...);
//EventHandler是一種委託,當作是函數指針類型
事件event是一種帶特殊簽名的委託的實例,且其原型聲明必須是以下形式:this
public delegate void EventHandler(object sender ,MyEventArgs e) ;
事件定義:spa
public event EventHandler ActionEvent;
控件類(或其餘能夠觸發事件的類):
class Control
{
public event EventHandler SomeEvent;//聲明能夠觸發的事件
//...
protected OnSomeEvent(EventArgs e) //觸發事件
{
if(SomeEvent)//判斷是否有註冊處理函數
{
SomeEvent(this, e);//這裏纔是觸發事件的實質部分!!
}
}
}
由於通常控件的觸發都是由操做系統檢測而後自動調用protected的成員OnSomeEvent(EventArg e)函數,既然是protected,意味着我沒有辦法直接經過程序模擬觸發事件的發生。固然你能夠自定義事件,而後決定什麼時候觸發。
下面是處理類:
class Consumer
{
private Control ctl0 = new Control();
//...
public Consumer()
{
//..
this.ctl0.SomeEvent += new System.EventHandler(this.ctl0_SomeEvent);
}
private ctl0_SomeEvent(object sender, EventArgs e)
{
//do things
}Win32/MFC 消息發送與回調函數機制
消息驅動機制 一、消息驅動與消息循環 「消息」是windows運行機制中一個基本而又重要的概念。消息是一個報告事件發生的通知,消息驅動是圍繞消息的產生與處理展開的,並依靠消息循環機制來實現。 從程序設計的觀點看,某條消息可被視爲某個事件的發生,好比點擊鼠標。事件便可以由用戶引起,也能夠由應用程序產生,固然Windows自己也能發出消息。Windows應用程序的消息來源有4種:輸入消息,控制消息,系統消息,用戶消息。 Windows是一個多任務操做系統,因此沒有哪個程序可以獨佔系統的資源,資源都是由Windows統一管理的。那麼某個程序是如何得到用戶的信息呢?事實上,Windows在時刻監視着用戶的每一個舉動,並分析用戶的動做與哪個程序相關,而後將動做以消息的形式發送給當前的應用程序。相反,應用程序也在時時等着消息的到來,一旦發現它的消息隊列中有未處理的信息,就獲取並分析該消息,並根據消息所包含的內容採起適當的動做來響應。這裏咱們引出另外一個概念「消息驅動」。好比當你單擊file菜單的時候,首先這個動做被windows所捕獲,而不是應用程序。經分析windows知道該動做該由哪一個應用程序處理,而後windows就發送WM_COMMAND消息給該應用程序,它告訴應用程序,你單擊了file菜單。應用程序得知這一消息後,便採起相應的動做來響應它,進行「消息處理」。Windows爲每一個線程維護了相應的消息隊列,應用程序的任務就是不停地從特定的消息隊列中獲取消息、分析消息並處理消息,直到消息(WM_QUIT)爲止。這個過程的程序結構稱爲「消息循環」。 二、消息傳送 發送消息和寄送消息 發送一個消息時,系統直接調用窗口進程。通訊是即時的。直到窗口進程爲調用函數返回一個結果後,應用程序才能繼續。 寄送一個消息時,系統把消息發送到擁有該窗口的應用程序消息隊列中。消息隊列是系統定義的一個內存塊,用於臨時存儲消息,或是把消息直接直接發給窗口過程。每一個窗口維護本身的消息隊列,從中取出消息,利用窗口函數進行處理。一有空閒,應用程序就搜索消息隊列,並在消息隊列中處理消息,即從隊列中刪除他們。調用函數發送消息後就當即返回,但結果只是表示消息寄送成功與否,而不表示被調用窗口進程的結果。一般鼠標和鍵盤消息是寄送的。 三、消息處理 Windows程序在處理消息時使用了「回掉函數」的特殊函數。這個函數由應用程序定義,但並不禁應用程序來調用,而是共操做系統或者其子系統來調用的。這種調用一般在某一事件發生,或者在窗口或字體被枚舉時發生。Windows向程序員所能發送的消息多達百種,可是,對於通常的應用程序來講,只是其中的一部分有意義。 四、Windows對消息驅動機制的支持 Windows操做系統包括3個內核基本模塊: GDI:負責在屏幕上繪製象素、打印硬考貝輸出,繪製用戶界面 KERNEL:支持與操做系統密切相關的功能。如進程加載,系統調用 USER:爲全部的用戶界面對象提供支持,它用於接收和管理全部輸入消息、系統消息,並把他們發給相應的窗口的消息隊列。 上述GDI、KERNEL和USESR模塊中的庫函數可被應用程序調用,也可被其餘程序模塊調用。Windows把包含庫函數的模塊稱爲EXPORT,在WINDOWS提供的一種新的EXE文件中有一個入口表用於指明模塊內每一個輸出函數的地址。 從應用程序方面,用到的庫函數被認爲是IMPORT函數。應用程序對一個入口函數發出的遠程調用可用不一樣的重定位表來肯定。幾乎全部的應用程序都至少包含一個入口庫函數或者稱爲被外部調用的函數。該windows庫函數通常來自某個程序模塊,用於從WINDOWS接收消息,該函數的使用標誌必須是EXPORT,這才能使WINDOWS容許它被一個外部模塊正常調用。