界面开发(一)--- Hook所有的窗体

     上篇文章界面开发概述,讲了我开发界面的一些心得体会和一些基本的原理,从这篇开始,我开始讲解一下我的界面开发的全部过程,一步一步的讲解开发界面的过程,这篇主要讲解的是Hook编程,Hook所有的窗体。

     Hook,对于大多数程序员来说,这个词并不陌生。对于Windows系统来说,消息Message的传递贯穿了整个系统,Message简单来说就是一个整数,它具有相应的意义。在C++的winuser.h中可以看到我们常用的很多的Message。Hook与Message是密不可分的,它的中文解释就是“钩子”,就是监控系统中Message的传递,就是在Message传递到最终的Message处理前,对特定的消息进行处理。

     对于Hook来说,开发主要的有3个API函数,均放在User32.dll文件中,这三个函数是:

Hook
 1           ///   <summary>
 2           ///  SetWindowsHookEx
 3           ///   </summary>
 4           ///   <param name="idHook"></param>
 5           ///   <param name="lpfn"></param>
 6           ///   <param name="hMod"></param>
 7           ///   <param name="dwThreadId"></param>
 8           ///   <returns></returns>
 9          [DllImport( " User32.dll " , CharSet  =  CharSet.Auto)]
10           public   static   extern  IntPtr SetWindowsHookEx( int  idHook, HookProc lpfn,  int  hMod,  int  dwThreadId);
11    
12           ///   <summary>
13           ///  CallNextHookEx
14           ///   </summary>
15           ///   <param name="hhk"></param>
16           ///   <param name="nCode"></param>
17           ///   <param name="wParam"></param>
18           ///   <param name="lParam"></param>
19           ///   <returns></returns>
20          [DllImport( " User32.dll " , CharSet  =  CharSet.Auto)]
21           public   static   extern  IntPtr CallNextHookEx(IntPtr hhk,  int  nCode, IntPtr wParam, IntPtr lParam);
22      
23           ///   <summary>
24           ///  UnhookWindowsHookEx
25           ///   </summary>
26           ///   <param name="hhk"></param>
27           ///   <returns></returns>
28          [DllImport( " User32.dll " , CharSet  =  CharSet.Auto)]
29           public   static   extern   bool  UnhookWindowsHookEx(IntPtr hhk);

 

     这三个方法分别就是添加Hook,释放Hook和执行下一个Hook。其中的参数就不必介绍了,网上有很多这方面的资料。

     接下来就是对Windows窗体的消息截取。

     我创建一个项目名称叫做SkinEngines,然后再NativeMethod中添加了这三个方法。其中SetWindowsHookEx中需要一个参数就是一个方面的名称,在C#中使用委托实现,所以也创建了一个专门保存委托的地点,放在Delegates.cs文件中。

HookProc
     ///   <summary>
    
///  HookProc -- HookProc
    
///   </summary>
    
///   <param name="nCode"></param>
    
///   <param name="wParam"></param>
    
///   <param name="lParam"></param>
    
///   <returns></returns>
     public   delegate  IntPtr HookProc( int  nCode, IntPtr wParam, IntPtr lParam);

 

     然后创建一个名为SkinEngine的Component。在SkinEngine的构造函数中添加了自己的一些操作,对窗体的Hook。代码如下:

  1  ///   <summary>
  2       ///  SkinEngine -- Skin All Form,Dialog,Control
  3       ///   </summary>
  4       public   partial   class  SkinEngine : Component
  5      {
  6           #region  Field
  7           ///   <summary>
  8           ///  CBTHook -- Hook WH_CBT
  9           ///   </summary>
 10           private   static  HookProc _cbtHook;
 11 
 12           ///   <summary>
 13           ///  Hook
 14           ///   </summary>
 15           private   static  IntPtr Hook;
 16 
 17           ///   <summary>
 18           ///  Current SkinEngine
 19           ///   </summary>
 20           internal   static  SkinEngine Engine;
 21 
 22           ///   <summary>
 23           ///  Skinned handled
 24           ///   </summary>
 25           internal   static  ArrayList SkinHandleList  =   new  ArrayList();
 26           #endregion
 27 
 28           #region  Constructor
 29           ///   <summary>
 30           ///  Constructor
 31           ///   </summary>
 32           public  SkinEngine()
 33          {
 34              InitializeComponent();
 35               //  Internal Constructor
 36               this .InternalConstructor();
 37          }
 38 
 39           ///   <summary>
 40           ///  Constructor With container
 41           ///   </summary>
 42           ///   <param name="container"></param>
 43           public  SkinEngine(IContainer container)
 44          {
 45              container.Add( this );
 46 
 47              InitializeComponent();
 48 
 49               //  Internal Constructor
 50               this .InternalConstructor();
 51          }
 52           #endregion
 53 
 54           #region  InternalConstructor
 55           ///   <summary>
 56           ///  the Internal Constructor to Create Hook and Get List of all control to skin.
 57           ///   </summary>
 58           private   void  InternalConstructor()
 59          {
 60               //  IsDesignMode == false
 61               if  ( ! IsDesignMode)
 62              {
 63                   //  Check Engine
 64                   if  (Engine  ==   null )
 65                  {
 66                       //  Set Engine
 67                      Engine  =   this ;
 68 
 69                       //  Hook Process
 70                       if  (Hook  ==  IntPtr.Zero)
 71                      {
 72                          _cbtHook  =   new  HookProc(SkinEngine.FnHookProc);
 73                          Hook  =  NativeMethod.SetWindowsHookEx( 5 , _cbtHook,  0 , AppDomain.GetCurrentThreadId());
 74                          Application.ApplicationExit  +=   new  EventHandler(Application_ApplicationExit);
 75                      }
 76                  }
 77              }
 78          }
 79           #endregion
 80 
 81           #region  FnHookProc
 82           ///   <summary>
 83           ///  FnHookProc
 84           ///   </summary>
 85           ///   <param name="nCode"></param>
 86           ///   <param name="wParam"></param>
 87           ///   <param name="lParam"></param>
 88           ///   <returns></returns>
 89           private   static   unsafe  IntPtr FnHookProc( int  nCode, IntPtr wParam, IntPtr lParam)
 90          {
 91               if  (Engine  !=   null )
 92              {
 93                   switch  (nCode)
 94                  {
 95                       case   5 :
 96                           //  Get Skin Control
 97                          Control control  =  Control.FromHandle(wParam);
 98                           //  Control is null it Can be Dialog
 99                           if  (control  ==   null )
100                          {
101                              StringBuilder builder  =   new  StringBuilder( 260 );
102                              NativeMethod.GetClassName(wParam, builder,  260 );
103                               //  #32770 is Dialog
104                               if  (builder.Length  ==   6   &&  builder.ToString()  ==   " #32770 " )
105                              {
106                                   //  Add to SkinHandleList
107                                  SkinHandleList.Add(wParam);
108                                   //  Print
109                                  Debug.WriteLine(builder.ToString());
110                              }
111                               break ;
112                          }
113                           if  ( ! SkinHandleList.Contains(wParam)  &&  (control  is  Form))
114                          {
115                               //  Add to SkinHandleList
116                              SkinHandleList.Add(wParam);
117                               //  Print all control's Name
118                              Debug.WriteLine(control.Name);
119                          }
120                           break ;
121                       default :
122                           break ;
123                  }
124              }
125               return  NativeMethod.CallNextHookEx(Hook, nCode, wParam, lParam);
126          }
127           #endregion
128 
129           #region  Application_ApplicationExit
130           ///   <summary>
131           ///  Application_ApplicationExit
132           ///   </summary>
133           ///   <param name="sender"></param>
134           ///   <param name="e"></param>
135           private   void  Application_ApplicationExit( object  sender, EventArgs e)
136          {
137              Engine.Dispose( false );
138          }
139           #endregion
140 
141           #region  Property
142           ///   <summary>
143           ///  Gets or sets a value indicating whether we are currently in design mode.
144           ///   </summary>
145           ///   <value>
146           ///       <c> true </c>  if this we are in design mode; otherwise,  <c> false </c> .
147           ///   </value>
148           internal   static   bool  IsDesignMode {  get set ; }
149           #endregion
150      }

 

      这样整个窗体就可以进行Hook,其中NativeMethod.SetWindowsHookEx设置了WM_CBT的消息,这个消息用来对Windows窗体的激活,显示。这样,窗体就会被我们记录下来,现在仅仅是将记录下来的窗体显示出来,写出了窗体的名称。结果如下:

     

      这篇就暂时写道这里,下一篇将对Form的消息进行Hook并绘制。

      代码:/Files/zhjp11/皮肤/SkinEngines20100318.rar

 

转载于:https://www.cnblogs.com/zhjp11/archive/2010/03/18/1688916.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值