最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

所有的有用戶界面的控件都繼承自Control,這種方式需要創(chuàng)建對應(yīng)控件的派生類,不能統(tǒng)一對各個窗口的消息進行攔截處理,因為從根本上說這兩者都是Windows的窗口過程,只有收到針對本窗口自身的消息。

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

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

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

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

三者都有一個共同的參數(shù)類型Message,它封裝了Windows消息。同時還包括一個很方便的ToString方法,可以將Message對象轉(zhuǎn)換成包括消息名稱(WM_XXX)在內(nèi)的字符串,通過Reflector可以看到實現(xiàn)是通過一個內(nèi)部類MessageDecoder,使用一個很長的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是消息對應(yīng)的窗口句柄,根據(jù)上面的分析可以知道在窗口過程(DefWndProc,WndProc)中收到的窗口句柄都是該窗口的句柄,而在PreFilterMessage中收到的消息的窗口句柄則根據(jù)觸發(fā)消息的窗口不同而不同。

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

//Declaring Type: System.Windows.Forms.Control //Assembly: System.Windows.Forms, Version=2.0.0.0 public static Control FromHandle(IntPtr handle);通過這種方式可以監(jiān)測各消息的信息來自哪個控件。
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)試輸出如下圖所示:

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

相關(guān)文章

  • C#多線程用法詳解

    C#多線程用法詳解

    本文詳細講解了C#多線程用法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12
  • C#基于Mongo的官方驅(qū)動手擼一個Super簡易版MongoDB-ORM框架

    C#基于Mongo的官方驅(qū)動手擼一個Super簡易版MongoDB-ORM框架

    本文給大家分享C#基于Mongo的官方驅(qū)動手擼一個簡易版MongoDB-ORM框架,是一款屬于super簡易版的,通過圖文的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-05-05
  • winform實現(xiàn)拖動文件到窗體上的方法

    winform實現(xiàn)拖動文件到窗體上的方法

    這篇文章主要介紹了winform實現(xiàn)拖動文件到窗體上的方法,以實例分析了C#中WinForm操作窗體及文件的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-09-09
  • C#中SQL參數(shù)傳入空值報錯解決方案

    C#中SQL參數(shù)傳入空值報錯解決方案

    這篇文章主要介紹了C#中SQL參數(shù)傳入空值報錯解決方案,需要的朋友可以參考下
    2017-06-06
  • C#使用Newtonsoft.Json庫實現(xiàn)JSON數(shù)據(jù)中某個字段值的提取功能

    C#使用Newtonsoft.Json庫實現(xiàn)JSON數(shù)據(jù)中某個字段值的提取功能

    在C#中,可以使用Newtonsoft.Json庫(也稱為Json.NET)來處理JSON數(shù)據(jù),下面將通過幾個示例來展示如何從JSON格式的文本中提取某個字段的值,并將其存儲到字符串、列表或其他泛型集合中,需要的朋友可以參考下
    2025-03-03
  • C#彩色圖片灰度化算法實例

    C#彩色圖片灰度化算法實例

    這篇文章主要介紹了C#彩色圖片灰度化算法,以實例形式對灰度化算法進行了較為詳細的介紹,非常具有實用價值,需要的朋友可以參考下
    2014-10-10
  • C#中的Task.Delay()和Thread.Sleep()區(qū)別(代碼案例)

    C#中的Task.Delay()和Thread.Sleep()區(qū)別(代碼案例)

    Task.Delay(),async/await和CancellationTokenSource組合起來使用可以實現(xiàn)可控制的異步延遲。本文通過多種代碼案例給大家分析C#中的Task.Delay()和Thread.Sleep()知識,感興趣的朋友一起看看吧
    2021-06-06
  • C#中的委托、事件學習筆記

    C#中的委托、事件學習筆記

    這篇文章主要介紹了C#中的委托、事件學習筆記,本文講解了委托delegate、事件的相關(guān)知識并給出代碼實例,需要的朋友可以參考下
    2015-01-01
  • C# 多進程打開PPT的示例教程

    C# 多進程打開PPT的示例教程

    這篇文章主要介紹了C# 多進程打開PPT的示例教程,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2021-01-01
  • 如何在C#中調(diào)用COM組件

    如何在C#中調(diào)用COM組件

    這篇文章主要介紹了如何在C#中調(diào)用COM組件,文中講解非常細致,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-07-07

最新評論

陈巴尔虎旗| 收藏| 通辽市| 松滋市| 乳源| 英超| 中西区| 荔波县| 鹿邑县| 甘谷县| 大余县| 浮山县| 泸州市| 青阳县| 玛沁县| 东乌珠穆沁旗| 沿河| 象州县| 随州市| 洞口县| 广安市| 阜阳市| 新余市| 温泉县| 思南县| 岚皋县| 瑞丽市| 东莞市| 延长县| 巢湖市| 千阳县| 洮南市| 大荔县| 从化市| 瓦房店市| 麻栗坡县| 南汇区| 扶风县| 澄江县| 田阳县| 南京市|