你说的那个啥
wcHandle
压根就是一个窗口句柄
而SetWindowsHookEx
的第三个参数是
模块句柄
也就是说
你回调函数所在的模块的一个句柄
然后
最后一个参数是
进程id
和你需要进程绑定就可以了
局部钩子
没有写过
一般都写全局
HHOOK
SetWindowsHookEx(int
idHook,
//
钩子的类型,即它处理的消息类型HOOKPROC
lpfn,
//
钩子子程的地址指针。如果dwThreadId参数为0//
或是一个由别的进程创建的线程的标识,//
lpfn必须指向DLL中的钩子子程。//
除此以外,lpfn可以指向当前进程的一段钩子子程代码。// 钩子函数的入口地址,当钩子钩到任何消息后便调用这个函数。HINSTANCE
hMod,
//
应用程序实例的句柄。标识包含lpfn所指的子程的DLL。//
如果dwThreadId
标识当前进程创建的一个线程,//
而且子程代码位于当前进程,hMod必须为NULL。//
可以很简单的设定其为本应用程序的实例句柄。DWORD
dwThreadId
//
与安装的钩子子程相关联的线程的标识符。//
如果为0,钩子子程与所有的线程关联,即为全局钩子。);
百科过来的
函数说明
简单来说钩子就是系统触发一定事件下要进行 *** 作的函数,但是不同的事件会有不同的附加信息,所以根据不同的事件也会在那个三个参数中传递不同的附加内容,就是处理方法的结构必须和系统定义好的结构相同才可以
下面是附加资料可以看一下
------------------------------------------------------------------------------------------------
首先说明一点,你的问题问得不是很恰当,因为钩子函数是回调函数,由系统规定参数,并传递参数,由你写好内容,然后由系统在一定触发条件下调用
例如你建立的是WH_MOUSE钩子, 那么MouseProc的三个参数由 *** 作系统(实际上是WIN32 平台)传递进来,意义分别是nCode怎么处理消息, wParam消息标识, lParam是一个MOUSEHOOKSTRUCT结构指针,而我们要做的就是利用这三个参数来完成自己想实现的功能,这正是回调函数的意义!
一般做钩子用到三个函数, 主要解决的是钩子函数的定义:
钩子有局部和远程两种类型, 与钩子相关的函数有:
1 建立钩子:SetWindowsHookEx, 其四个参数分别为钩子类型, 钩子函数地址, 钩子函数所在DLL的实例句柄,安装钩子后想监控的线程的ID号, 返回参数为钩子句柄
2 UnhookWindowsHookEx, 参数只有一个,为要卸载的钩子句柄
3 钩子函数(名称任意), 三个参数, 具体意义与钩子类型有关
下面再举一个简单例子:
比如你想写一个程序, 当鼠标移到哪里时就在主程序中显示鼠标所在窗口的名称
--------------------
(1)如果鼠标只是局限在窗口内, 那么以上1, 2, 3三个函数均写在运行的主程序中, 比如函数1可以写在按下某个按钮的消息响应函数中,函数 2 写在松开按扭的消息响应函数中,函数 3 只要不写在别的函数中就行, 因为它本生就是一个要定义的独立函数
(2)如果鼠标可以在屏幕任意位置移动, 那么以上函数1, 2位置同(1), 但函数3要写在一个另外写的DLL里, 因为此时安装的是全局钩子, 为了达到获取窗口名称的目的, 在DLL里可能还要做一些其他工作,比如设置共享段, 关于这些这里不细说了
------------------------
如果你想问的是如何填充SetWindowsHookEx的参数 或 钩子函数的三个参数的具体意义, 那么可以参考MSDN, 因为参数与钩子类型, 要挂钩的消息有关
按事件分类
有如下的几种常用类型
(1)键盘钩子和低级键盘钩子可以监视各种键盘消息。
(2) 鼠标钩子和低级鼠标钩子可以监视各种鼠标消息。
(3) 外壳钩子可以监视各种Shell事件消息。比如启动和关闭应用程序。
(4)日志钩子可以记录从系统消息队列中取出的各种事件消息。
(5) 窗口过程钩子监视所有从系统消息队列发往目标窗口的消息。
此外,还有一些特定事件的钩子提供给我们使用,不一一列举。
按使用范围分类
主要有线程钩子和系统钩子
(1) 线程钩子监视指定线程的事件消息。
(2)系统钩子监视系统中的所有线程的事件消息。因为系统钩子会影响系统中所有的应用程序,所以钩子函数必须放在独立的动态链接库(DLL)中。这是系统钩子和线程钩子很大的不同之处。
几点需要说明的地方:
(1) 如果对于同一事件(如鼠标消息)既安装了线程钩子又安装了系统钩子,那么系统会自动先调用线程钩子,然后调用系统钩子。
(2) 对同一事件消息可安装多个钩子处理过程,这些钩子处理过程形成了钩子链。当前钩子处理结束后应把钩子信息传递给下一个钩子函数。而且最近安装的钩子放在链的开始,而最早安装的钩子放在最后,也就是后加入的先获得控制权。
(3) 钩子特别是系统钩子会消耗消息处理时间,降低系统性能。只有在必要的时候才安装钩子,在使用完毕后要及时卸载。
C#是面向对象的编程语言,所以钩子是写在类中的。
/// <summary>/// 设置的钩子类型
/// </summary>
public enum HookType : int
{
/// <summary>
/// WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks使我们可以把守菜单,迁移转变
///条,消息框,对话框消息并且发明用户应用ALT+TAB or ALT+ESC 组合键切换窗口。
///WH_MSGFILTER Hook只能把守传递到菜单,迁移转变条,消息框的消息,以及传递到通
///过安装了Hook子过程的应用法度建树的对话框的消息。WH_SYSMSGFILTER Hook
///把守所有应用法度消息。
///WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks使我们可以在模式轮回时代
///过滤消息,这等价于在主消息轮回中过滤消息。
///经由过程调用CallMsgFilter function可以直接的调用WH_MSGFILTER Hook。经由过程应用这
///个函数,应用法度可以或许在模式轮回时代应用雷同的代码去过滤消息,如同在主消息循
///环里一样
/// </summary>
WH_MSGFILTER = -1,
/// <summary>
/// WH_JOURNALRECORD Hook用来把守和记录输入事务。典范的,可以应用这
///个Hook记录连气儿的鼠标和键盘事务,然后经由过程应用WH_JOURNALPLAYBACK Hook
///往返放。WH_JOURNALRECORD Hook是全局Hook,它不克不及象线程特定Hook一样
///应用。WH_JOURNALRECORD是system-wide local hooks,它们不会被打针到任何行
///程地址空间
/// </summary>
WH_JOURNALRECORD = 0,
/// <summary>
/// WH_JOURNALPLAYBACK Hook使应用法度可以插入消息到体系消息队列。可
///以应用这个Hook回放经由过程应用WH_JOURNALRECORD Hook记录下来的连气儿的鼠
///标和键盘事务。只要WH_JOURNALPLAYBACK Hook已经安装,正常的鼠标和键盘
///事务就是无效的。WH_JOURNALPLAYBACK Hook是全局Hook,它不克不及象线程特定
///Hook一样应用。WH_JOURNALPLAYBACK Hook返回超时价,这个值告诉体系在处
///理来自回放Hook当前消息之前须要守候多长时候(毫秒)。这就使Hook可以把握实
///时事务的回放。WH_JOURNALPLAYBACK是system-wide local hooks,它们不会被
///打针到任何行程地址空间
/// </summary>
WH_JOURNALPLAYBACK = 1,
/// <summary>
/// 在应用法度中,WH_KEYBOARD Hook用来把守WM_KEYDOWN and
///WM_KEYUP消息,这些消息经由过程GetMessage or PeekMessage function返回。可以使
///用这个Hook来把守输入到消息队列中的键盘消息
/// </summary>
WH_KEYBOARD = 2,
/// <summary>
/// 应用法度应用WH_GETMESSAGE Hook来把守从GetMessage or PeekMessage函
///数返回的消息。你可以应用WH_GETMESSAGE Hook去把守鼠标和键盘输入,以及
///其它发送到消息队列中的消息
/// </summary>
WH_GETMESSAGE = 3,
/// <summary>
/// 把守发送到窗口过程的消息,体系在消息发送到接管窗口过程之前调用
/// </summary>
WH_CALLWNDPROC = 4,
/// <summary>
/// 在以下事务之前,体系都邑调用WH_CBT Hook子过程,这些事务包含:
///1 激活,建树,烧毁,最小化,最大化,移动,改变尺寸等窗口事务;
///2 完成体系指令;
///3 来自体系消息队列中的移动鼠标,键盘事务;
///4 设置输入核苦衷务;
///5 同步体系消息队列事务。
///Hook子过程的返回值断定体系是否容许或者防止这些 *** 纵中的一个
/// </summary>
WH_CBT = 5,
/// <summary>
/// WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks使我们可以把守菜单,迁移转变
///条,消息框,对话框消息并且发明用户应用ALT+TAB or ALT+ESC 组合键切换窗口。
///WH_MSGFILTER Hook只能把守传递到菜单,迁移转变条,消息框的消息,以及传递到通
///过安装了Hook子过程的应用法度建树的对话框的消息。WH_SYSMSGFILTER Hook
///把守所有应用法度消息。
///WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks使我们可以在模式轮回时代
///过滤消息,这等价于在主消息轮回中过滤消息。
///经由过程调用CallMsgFilter function可以直接的调用WH_MSGFILTER Hook。经由过程应用这
///个函数,应用法度可以或许在模式轮回时代应用雷同的代码去过滤消息,如同在主消息循
///环里一样
/// </summary>
WH_SYSMSGFILTER = 6,
/// <summary>
/// WH_MOUSE Hook把守从GetMessage 或者 PeekMessage 函数返回的鼠标消息。
///应用这个Hook把守输入到消息队列中的鼠标消息
/// </summary>
WH_MOUSE = 7,
/// <summary>
/// 当调用GetMessage 或 PeekMessage 来从消息队列种查询非鼠标、键盘消息时
/// </summary>
WH_HARDWARE = 8,
/// <summary>
/// 在体系调用体系中与其它Hook接洽关系的Hook子过程之前,体系会调用
///WH_DEBUG Hook子过程。你可以应用这个Hook来决意是否容许体系调用与其它
///Hook接洽关系的Hook子过程
/// </summary>
WH_DEBUG = 9,
/// <summary>
/// 外壳应用法度可以应用WH_SHELL Hook去接管首要的通知。当外壳应用法度是
///激活的并且当顶层窗口建树或者烧毁时,体系调用WH_SHELL Hook子过程。
///WH_SHELL 共有5钟景象:
///1 只要有个top-level、unowned 窗口被产生、起感化、或是被摧毁;
///2 当Taskbar须要重画某个按钮;
///3 当体系须要显示关于Taskbar的一个法度的最小化情势;
///4 当今朝的键盘布局状况改变;
///5 当应用者按Ctrl+Esc去履行Task Manager(或雷同级此外法度)。
///遵守常规,外壳应用法度都不接管WH_SHELL消息。所以,在应用法度可以或许接
///收WH_SHELL消息之前,应用法度必须调用SystemParametersInfo function注册它自
///己
/// </summary>
WH_SHELL = 10,
/// <summary>
/// 当应用法度的前台线程处于余暇状况时,可以应用WH_FOREGROUNDIDLE
///Hook履行低优先级的任务。当应用法度的前台线程可能要变成余暇状况时,体系就
///会调用WH_FOREGROUNDIDLE Hook子过程
/// </summary>
WH_FOREGROUNDIDLE = 11,
/// <summary>
/// 把守发送到窗口过程的消息,体系在消息发送到接管窗口过程之后调用
/// </summary>
WH_CALLWNDPROCRET = 12,
/// <summary>
/// 把守输入到线程消息队列中的键盘消息
/// </summary>
WH_KEYBOARD_LL = 13,
/// <summary>
/// 把守输入到线程消息队列中的鼠标消息
/// </summary>
WH_MOUSE_LL = 14
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("USER32DLL")]
private static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);//导入钩子函数消息传递的方法
[DllImport("USER32DLL")]
private static extern IntPtr SetWindowsHookEx(HookType idHook, HookProc lpfn, IntPtr hMod, int dwThreadId);//导入设置钩子的方法
[DllImport("user32dll", CharSet = CharSetAuto, CallingConvention = CallingConventionStdCall)]
private static extern bool UnhookWindowsHookEx(int idHook);
//导入卸载钩子的方法
private delegate int HookProc(int nCode, int wParam, IntPtr lParam); //声明回调函数
///<summary>
///自定义回调函数
///</summary>
private int HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
MessageBoxShow(nCodeToString());
//键盘按下时
if (nCode >= 0 && wParam == (IntPtr)0)
{
int vkCode = MarshalReadInt32(lParam);
Keys key = (Keys)vkCode;
MessageBoxShow(keyToString());
}
return CallNextHookEx(handle, nCode, wParam, lParam);
}
private void Form1_Load(object sender, EventArgs e)
{
//创建钩子(这个函数的参数你可以百度找找,C#钩子研究过但没成功)
SetWindowsHookEx(params);
}
}
很多人都以为未排泄是大问题,其实不是,一个触发没有排泄是不会导致死机的,他只会在运行几千次以后造成游戏卡顿。而直接死机的原因大部分是因为触发没写好不断循环造成。
你这个触发本身没有问题,看看是不是钩子导致了其他触发不停循环,基本可以肯定问题出在其他触发,而不是这里。
以上就是关于c#特定程序的钩子全部的内容,包括:c#特定程序的钩子、易语言钩子、钩子程序的分类等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)