惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
爱范儿
爱范儿
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
V
V2EX
博客园_首页
Engineering at Meta
Engineering at Meta
博客园 - 聂微东
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Apple Machine Learning Research
Apple Machine Learning Research
GbyAI
GbyAI
H
Help Net Security
A
About on SuperTechFans
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Blog — PlanetScale
Blog — PlanetScale
W
WeLiveSecurity
云风的 BLOG
云风的 BLOG
D
Docker
Security Archives - TechRepublic
Security Archives - TechRepublic
Help Net Security
Help Net Security
N
News and Events Feed by Topic
Simon Willison's Weblog
Simon Willison's Weblog
G
Google Developers Blog
A
Arctic Wolf
T
The Blog of Author Tim Ferriss
博客园 - 叶小钗
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Google DeepMind News
Google DeepMind News
博客园 - 三生石上(FineUI控件)
aimingoo的专栏
aimingoo的专栏
Hacker News: Ask HN
Hacker News: Ask HN
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 司徒正美
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy International News Feed
T
Troy Hunt's Blog
T
Tenable Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Recorded Future
Recorded Future
F
Fortinet All Blogs
D
DataBreaches.Net
B
Blog
T
Threat Research - Cisco Blogs
MyScale Blog
MyScale Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
The GitHub Blog
The GitHub Blog
Security Latest
Security Latest
M
MIT News - Artificial intelligence

博客园 - 萧萧空间

Windows 2003,XP安装Windows Phone 7 从海量数据中找出中位数(转) 界面开发(五)--- 界面优化 界面开发(四)--- 还窗体的新面貌 界面开发(三)--- 设置窗体的Region 界面开发(二)--- NativeWindow 界面开发概述 ExtJs扩展之GroupPropertyGrid ExtJs之带图片的下拉列表框 寻找第K大的数的方法总结 我自己的ColorSpy Office 2010 beta版安装 Java反编译工具JD ExtJs Grid Drag Drap Splash窗体(ProgressWindowForm修改) 异步窗体实现操作进度(ProgressWindow) 线程封装组件(BackgroundWorker)和线程(Thread) 多线程开发 NSIS 的使用心得
界面开发(一)--- Hook所有的窗体
萧萧空间 · 2010-03-18 · via 博客园 - 萧萧空间

     上篇文章界面开发概述,讲了我开发界面的一些心得体会和一些基本的原理,从这篇开始,我开始讲解一下我的界面开发的全部过程,一步一步的讲解开发界面的过程,这篇主要讲解的是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 { getset; }
149         #endregion
150     }

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

     

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

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