標籤:style blog class c ext color
在C#編程中,經常會遇到一些情境,如禁止滑鼠拖動表單,啟用某些快速鍵,禁止滑鼠移動等。遇到這些需求,可以通過表單的MouseMove事件,OnDragDrop,OnMove等事件來解決問題,
但是該方法有個缺點是,只能在當前表單或控制項上起作用,如果表單或控制項被覆蓋,就不起作用了。而我們在開發時經常會碰到一個Form上有很多控制項的情形,本節將講述如何通過捕捉windows訊息的方式來實現這個功能。
一般來講,實現該功能有兩種方法,
1. 通過重寫WndProc(ref Message m)來實現,方法簽名如下:
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
}
其中的Message中包含了以下幾個欄位資訊,是和windows訊息相關的,
public IntPtr LParam { get; set; }
public int Msg { get; set; } // 擷取或設定訊息的 識別碼。
public IntPtr WParam { get; set; }
如:
如果我們要禁用表單的拖拽,代碼如下:
const int WM_NCLBUTTONDOWN = 0x00A1; const int HTCAPTION = 2; protected override void WndProc(ref Message m) { if (m.Msg == WM_NCLBUTTONDOWN && m.WParam.ToInt32() == HTCAPTION) return; base.WndProc(ref m); }
2. 通過繼承介面來實現System.Windows.Forms.IMessageFilter介面實現,介面聲明如下:
public interface IMessageFilter
{
// 摘要:
// 在調度訊息之前將其篩選出來。
//
// 參數:
// m:
// 要調度的訊息。無法修改此訊息。
//
// 返回結果:
// 如果篩選訊息並禁止訊息被調度,則為 true;如果允許訊息繼續到達下一個篩選器或控制項,則為 false。
bool PreFilterMessage(ref Message m);
}
還以禁止拖動表單為例,實現MessageFilter類如下:
public class MessageFilter : System.Windows.Forms.IMessageFilter { const int WM_NCLBUTTONDOWN = 0x00A1;//當游標在視窗的非客戶區並按下滑鼠左鍵時發送此訊息 const int HTCAPTION = 2; public bool PreFilterMessage(ref System.Windows.Forms.Message m) { if (m.Msg == WM_NCLBUTTONDOWN && m.WParam.ToInt32() == HTCAPTION) return true; return false; } }
建立完這個類後,建立一個對象,並把該對象添加到應用程式裡邊,如下列代碼,下列代碼是Program檔案當中的入口方法 static class Program { private static MessageFilter filter = new MessageFilter(); /// <summary> /// 應用程式的主進入點。 /// </summary> [STAThread] static void Main() { Application.AddMessageFilter(filter); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainFrm()); } }
注意:實現IMessageFilter介面時,一定要注意其傳回值, [如果篩選訊息並禁止訊息被調度,則為 true;如果允許訊息繼續到達下一個篩選器或控制項,則為 false。] ,對攔截的訊息處理之後,一定要注意對傳回值進行處理,如果對不處理的訊息,一定要返回為false,讓其他的控制項去處理訊息。
關於Windows訊息,請參考文章 http://www.cnblogs.com/lenmom/p/3730179.html