最近幾天做項目的時候,遇到了一個截取視窗訊息的問題,從網上搜了一些資料後,也有了些自己的理解,隨後又忽然想起了Winform的事件模型。於是便寫下來與大家分享。
首先,我們先回憶一下VC++的Windows編程。我不說細節,只說大概的互動過程。比如視窗上有一個按鈕,當我們單機這個按鈕的時候,作業系統會嚮應用程式發一個按一下滑鼠的訊息,當按鈕這個對象捕捉到這個訊息的時候,就會進行相應的處理。作業系統中定義了非常多的訊息關於作業系統訊息的知識,請參見 http://bbs.cfan.com.cn/thread-555997-1-1.html 。 下面,介紹一下在 .net 環境下如果截取視窗訊息。首先,建立一個Winform應用程式,在Form1.cs中,加入下列代碼
//截取訊息,進行處理
protected override void WndProc(ref Message m)
{
switch(m.Msg)
{
case 17:
MessageBox.Show("哈哈,你不能關閉電腦!");
m.Result=(IntPtr)0;
break;
case 513:
MessageBox.Show("哈哈,你不能點擊左鍵!");
m.Result=(IntPtr)0;
break;
case 516:
MessageBox.Show("哈哈,你不能點擊右鍵!");
m.Result=(IntPtr)0;
break;
default:
base.WndProc(ref m);
break;
}
}
其中,WndProc方法是Form類中的方法(其實,它是Control類中定義的虛方法,在Form類中給出了實現)
它的作用是接收來自作業系統的訊息,然後進行相應的處理。
我們複寫了它,就可以優先以我們的方式來擷取視窗訊息。但是,不能忘記調用base.WndProc(ref m),否則,程式出錯的可能性比較大。
下面,我們說一下事件模型。
我相信有一大批入門級的程式員,包括我之前在內,都會WinForm的事件模型特別好奇,因為的確微軟把他封裝的非常好,非常簡單,雙擊控制項觸發一個事件,然後再在自動產生的程式碼中寫邏輯。現在我們來想一想,這是怎麼實現的呢?為什麼你單機一下按鈕,對應的按鈕事件的邏輯就會執行呢?也許你會說,因為有這一句代碼,
this.button1.Click += new System.EventHandler(this.button1_Click);
不錯,這句代碼是註冊了一個Click事件,但是,事件也是需要調用的啊,那麼,到底是誰,在什麼時候調用的呢?我本人的感覺,應該是Form對象在截取視窗訊息的時候,如果捕獲到了某訊息,就會查看是否註冊了與該訊息對應的事件,如果該事件被註冊了,那麼,就會調用該事件的對象來執行委託鏈。