您好,欢迎来到爱玩科技网。
搜索
您的当前位置:首页Net实现钩子函数(Hook)以及通过SendMessage实现自动点击按钮和给文本框赋值

Net实现钩子函数(Hook)以及通过SendMessage实现自动点击按钮和给文本框赋值

来源:爱玩科技网
Net实现钩⼦函数(Hook)以及通过SendMessage实现⾃动点击

按钮和给⽂本框赋值

1.实现钩⼦函数

钩⼦(Hook)的实现需要三个主要的函数和⼀个委托

[DllImport(\"user32.dll\

public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);//设置系统钩⼦[DllImport(\"user32.dll\private static extern bool UnhookWindowsHookEx(int idHook);//卸载系统钩⼦

[DllImport(\"user32.dll\

public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);//调⽤下⼀个钩⼦函数public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);//⽤于处理Hook住的消息

当我们在执⾏⼀个操作的时候,⾸先不是由我们的窗体获得消息,⽽是系统获得,然后系统再把消息发送到对应的窗体,Hook就是在窗体获取到信息之前抓住信息,然后对信息进⾏处理,然后可以传递给船体继续执⾏,或者就不传递给窗体

当在HookProc处理消息的时候,如果return 1,那么消息就会被截断,不会再传递到⽬标窗⼝,如果return的是CallNextHookEx那么就会继续调⽤下⼀个钩⼦,如果下⾯没有钩⼦了,那么消息就会被传递到⽬标窗体进⾏处理SetWindowsHookEx第⼀个参数是需要勾住的消息类型,总共14种消息类型,如下public const int WH_JOURNALRECORD = 0;

public const int constWH_JOURNALPLAYBACK = 1;public const int WH_KEYBOARD = 2;public const int WH_GETMESSAGE = 3;public const int WH_CALLWNDPROC = 4;public const int WH_CBT = 5;

public const int WH_SYSMSGFILTER = 6;public const int WH_MOUSE = 7;

public const int WH_HARDWARE = 8;public const int WH_DEBUG = 9;public const int WH_SHELL = 10;

public const int WH_FOREGROUNDIDLE = 11;public const int WH_CALLWNDPROCRET = 12;public const int WH_KEYBOARD_LL = 13;public const int WH_MOUSE_LL = 14;

第⼆个参数就是HookProc委托,⽤于对钩住的消息进⾏处理,

第三个参数是需要钩住的实例的句柄,最后⼀个是钩住的线程,如果是0则是全局钩住返回值为抓住的钩⼦的ID

UnhookWindowsHookEx卸载掉钩⼦,参数为上⾯返回的ID 辅助函数

[DllImport(\"kernel32.dll\")]

public static extern IntPtr GetModuleHandle(string name);//根据模块名称获取到对应的句柄[DllImport(\"user32.dll\

private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);//查询⼀个窗体[DllImport(\"User32.dll\

private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);//获取窗体中的所有⼦窗体(⽂本框,按钮等,都属于窗体)

[DllImport(\"user32.dll\")]

public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam);//枚举窗体中的所有⼦窗体public delegate bool CallBack(IntPtr hwnd, int lParam);

此委托是EnumChildWindows的回调函数,⽤于遍历的时候对窗⼝进⾏处理

根据Module的名字获取到对应的句柄SetWindowsHookEx的第三个参数可以使⽤这个函数来获得。下⾯是⼀个⽰例程序,设置⼀个全局钩⼦,作⽤是,如果输⼊的字符是⼩写字母,则直接转换为⼤写字母。1.1 HookProc的⽅法实现

private int MessageHandle(int nCode, Int32 wParam, IntPtr lParam) {

if (0x100 == wParam || 0x101 == wParam) //如果按键为按下状态,如果没有这句判断,则内部代码会执⾏两遍,⼀遍是KeyDown⼀遍是KeyUp {

KBDLLHOOKSTRUCT ks = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT)); //将所有的⼩写字母直接加1

if (ks.vkCode >= 65 && ks.vkCode <= 90) {

string cUpper = Convert.ToChar(ks.vkCode).ToString().ToUpper(); SendMessage(txtHandle, 0x0c, IntPtr.Zero, cUpper); } }

return CallNextHookEx(result, nCode, 0, lParam); }

1.2 KBDLLHOOKSTRUCT结构体(这个结构体因为不同的钩⼦内容会不⼀样)public struct KBDLLHOOKSTRUCT {

public int vkCode; public int scanCode; public int flags; public int time;

public IntPtr dwExtraInfo; }

1.3设置钩⼦和卸载钩⼦(两个按钮的事件)

private void btnInstallHook_Click(object sender, EventArgs e) {

HookProc hProc = new HookProc(MessageHandle);

IntPtr cInstance = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName); result = SetWindowsHookEx(HookHelper.WH_KEYBOARD_LL, hProc, cInstance, 0);

}

private void btnUnhook_Click(object sender, EventArgs e) {

UnhookWindowsHookEx(result); }

辅助⽅法:为了获取到窗体中的⽂本框的句柄//枚举窗体中的⼦窗体的回调函数

private bool EnumWindow(IntPtr hwnd, int lParam) {

StringBuilder sb=new StringBuilder(); GetWindowText(hwnd, sb, 10); if (sb.ToString() == \"HookTest\") {

txtHandle = hwnd; }

return true; }

2.SendMessage的使⽤

可以使⽤SendMessage模拟给发送⼀条系统消息[DllImport(\"user32.dll\

private static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

[DllImport(\"User32.dll\

private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);//发送消息,此重载⽅法可以直接给⽂本框赋值

下⾯是⼀个⾃动点击按钮和⾃动给⽂本框赋值的⽰例

private void btnTest_Click(object sender, EventArgs e) {

#region ⾃动点击按钮

//IntPtr cProcess = FindWindow(null, \"测试Hook\");

//winHandle = FindWindowEx(cProcess, IntPtr.Zero, null, \"点击显⽰界⾯\");

////SendMessage(winHandle, 0xf5, 0, 0);//0xf5 BM_CLICK 按钮单击对应的消息--经过测试,直接使⽤0xf5⽆法实现点击按钮的功能 ////测试结果发现,如果想要实现单击按钮的功能,必须先按下⿏标左键,再抬起⿏标左键

//SendMessage(winHandle, 0x201, IntPtr.Zero, IntPtr.Zero);//0x201 WM_LBUTTONDOWN 按下⿏标左键对应的消息 //SendMessage(winHandle, 0x202, IntPtr.Zero, IntPtr.Zero);//0x201 WM_LBUTTONUP 抬起⿏标左键对应的消息

#endregion

#region ⾃动输⼊⽂本

//IntPtr cProcess = FindWindow(null, \"Test.txt - 记事本\"); //winHandle = FindWindowEx(cProcess, IntPtr.Zero, null, \"\");

//IntPtr cProcess = FindWindow(null, \"测试Hook\");

//winHandle = FindWindowEx(cProcess, IntPtr.Zero, null, null);

////winHandle = new IntPtr(0xE10F2);//这种⽅式是先通过Spy++找到控件的句柄,然后再使⽤这个句柄进⾏数据交互(此⽅法每次重启窗体,对应的句柄都会发⽣变化)

//SendMessage(txtHandle, 0x0c, IntPtr.Zero, \"ABCDEFGHIJKLMN\");//0x0c wm_settext 给窗体设置⽂本 #endregion }

源代码:https://files.cnblogs.com/files/ckym/HookTest.rar

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- aiwanbo.com 版权所有 赣ICP备2024042808号-3

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务