欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

WinForm中DefWndProc、WndProc與IMessageFilter的區(qū)別

 更新時(shí)間:2014年08月27日 09:34:20   投稿:shichen2014  
這篇文章主要介紹了WinForm中DefWndProc、WndProc與IMessageFilter的區(qū)別,較為詳細(xì)的分析了WinForm的消息處理機(jī)制,需要的朋友可以參考下

一般來說,Winform的消息處理機(jī)制多數(shù)時(shí)候是通過事件處理程序進(jìn)行的,但當(dāng)沒有對(duì)應(yīng)的事件時(shí)通常的做法是聲明DefWndProc或者WndProc或者IMessageFilter,經(jīng)常在網(wǎng)上看見有文章將三者并列,那么它們有什么區(qū)別呢?本文對(duì)此做一簡(jiǎn)單分析如下:

DefWndProc和WndProc都是繼承自Control類中的虛方法,其原型如下:

protected override void DefWndProc(ref Message m)
{
 ....
   base.DefWndProc(m);
}
  
protected override void WndProc(ref Message m);
{
 .....
   base.WndProc(m);
}

所有的有用戶界面的控件都繼承自Control,這種方式需要?jiǎng)?chuàng)建對(duì)應(yīng)控件的派生類,不能統(tǒng)一對(duì)各個(gè)窗口的消息進(jìn)行攔截處理,因?yàn)閺母旧险f這兩者都是Windows的窗口過程,只有收到針對(duì)本窗口自身的消息。

通過復(fù)習(xí)Windows的消息處理機(jī)制,對(duì)這三者的關(guān)系可以有更好的理解。應(yīng)用程序的消息來自于系統(tǒng)消息隊(duì)列,被應(yīng)用程序的主程序中的消息循環(huán)所處理。這個(gè)消息循環(huán)從應(yīng)用程序的消息隊(duì)列中取出消息,進(jìn)行預(yù)處理,然后派發(fā)到消息對(duì)應(yīng)的窗口過程,窗口過程在被調(diào)用后根據(jù)消息的類型進(jìn)行相應(yīng)的處理,有些可以由Windows默認(rèn)處理的消息就調(diào)用Windows的DefWindowProc。

這里的WndProc就是對(duì)應(yīng)控件窗口的窗口過程,而DefWndProc會(huì)被WndProc調(diào)用,處理那些WndProc中未處理的消息(包括WndProc未吞掉的),因此DefWndProc收到的消息會(huì)比WndProc少。

IMessageFilter的調(diào)用發(fā)生在應(yīng)用程序的消息循環(huán)中,是消息預(yù)處理的一部分,所以它收到的消息是更全的(除了直接發(fā)送到窗口過程不進(jìn)入消息隊(duì)列的那些消息)。使用方式如下:

public class MessageFilter : IMessageFilter
{
 public bool PreFilterMessage(ref Message msg)
 {
   //識(shí)別消息并處理
  //return true;//吞掉消息,不派發(fā)
   return false;//進(jìn)入下一步派發(fā)到對(duì)應(yīng)窗口過程
 }
}
  
//在應(yīng)用程序消息循環(huán)中加入消息過濾器
MessageFilter f = new MessageFilter(this.lbMsg);
Application.AddMessageFilter(f);

三者都有一個(gè)共同的參數(shù)類型Message,它封裝了Windows消息。同時(shí)還包括一個(gè)很方便的ToString方法,可以將Message對(duì)象轉(zhuǎn)換成包括消息名稱(WM_XXX)在內(nèi)的字符串,通過Reflector可以看到實(shí)現(xiàn)是通過一個(gè)內(nèi)部類MessageDecoder,使用一個(gè)很長(zhǎng)的switch語句將消息ID轉(zhuǎn)換成消息名稱。

Message的定義如下:

[StructLayout(LayoutKind.Sequential), SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
public struct Message
{
   private IntPtr hWnd;
   private int msg;
   private IntPtr wparam;
   private IntPtr lparam;
   private IntPtr result;
   public IntPtr HWnd { get; set; }
   public int Msg { get; set; }
   public IntPtr WParam { get; set; }
   public IntPtr LParam { get; set; }
   public IntPtr Result { get; set; }
   public object GetLParam(Type cls);
   public static Message Create(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam);
   public override bool Equals(object o);
   public static bool operator !=(Message a, Message b);
   public static bool operator ==(Message a, Message b);
   public override int GetHashCode();
   public override string ToString();
}
  

其中hWnd是消息對(duì)應(yīng)的窗口句柄,根據(jù)上面的分析可以知道在窗口過程(DefWndProc,WndProc)中收到的窗口句柄都是該窗口的句柄,而在PreFilterMessage中收到的消息的窗口句柄則根據(jù)觸發(fā)消息的窗口不同而不同。

在PreFilterMessage中收到消息時(shí),可以使用Control.FromHandle得到窗口對(duì)應(yīng)的控件對(duì)象,原型如下:

//Declaring Type: System.Windows.Forms.Control //Assembly: System.Windows.Forms, Version=2.0.0.0 public static Control FromHandle(IntPtr handle);通過這種方式可以監(jiān)測(cè)各消息的信息來自哪個(gè)控件。
public bool PreFilterMessage(ref Message msg)
{
   Control c = Control.FromHandle(msg.HWnd);
   if (c == null)
      System.Diagnostics.Debug.WriteLine("Filter:NULL" +"-" + msg.ToString());
   else
      System.Diagnostics.Debug.WriteLine("Filter:" +c.Name+"-"+ msg.ToString());
   return false;
}

從Visual Studio的輸出窗口監(jiān)視到的調(diào)試輸出如下圖所示:

希望本文所述分析對(duì)大家深入理解WinForm的消息處理機(jī)制有所幫助。

相關(guān)文章

最新評(píng)論