程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 界面開發(一)--- Hook所有的窗體

界面開發(一)--- Hook所有的窗體

編輯:關於.NET

這篇開始,我開始講解一下我的界面開發的全部過程,一步一步的講解開發界面的過程,這 篇主要講解的是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並繪制。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved