Delphi中的消息钩子函数和Windows子类处理 入门…

2008-04-11 12:27:12来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

首先感谢各位老鸟这么久以来对小弟那么多的指导,给小弟提供N多的帮助,所以才
能让我的第一篇技术文章可以这么快和大家见面!也趁今天是小弟20岁生日呵呵,没人给
我庆祝,所以写篇文章做个纪念,也祝我自己生日快乐! ^o^

小弟我学习Delphi算起来也有半年时间,看到网上很多朋友对HOOK非常的感兴趣。
所以即兴写了一篇文章,在CSDN里小弟曾经发过一篇《Delphi的MU窗口代码》(惭愧啊)
由于那时候学的不久,所以有很多地方不是很完善,借此文章重新向大家详细介绍一下
Windows下的消息钩子函数的用法和Windows的子类处理,希望对你们有帮助。

好了,废话了这么久,也该进入正题了,关于HOOK的介绍就不再此介绍了,以前有
很多例子和文章可以参考,实在不行google或者baidu一下!^_^

首先我们先看一下安装HOOK的函数:


HHOOK SetWindowsHookEx(
int idHook, //要安装的HOOK的类型
HOOKPROC lpfn, //HOOK的回调函数
HINSTANCE hMod, //进程
DWORD dwThreadId //程序的线程,如果为0则是全局HOOK
);

熟悉了SetWindowsHookEx函数,我们就能开始我们的工作,挂钩进程。
首先打开Delphi,创建一个DLL工程(DLL Wizard)。然后创建一个新的单元(Unit1)。
首先在单元的 interface 下面声明要用到的函数。


var
OldHook:HHOOK;
Histance:HISTANCE;
OldProc:FARPROC;


我们的第一个函数是安装HOOK,让我们看一下代码:

Function SetHook:Boolean;stdcall;
begin
OldHook:=SetWindowsHookEx(WH_KEYBOARD,@HookProc,Histance,0);
if (OldHook=0) then exit else Result:=True;
end;

这样的话就安装一个全局的键盘HOOK,HOOK的方法还有很多,在此就不一一列举了。

下面介绍一下回调函数:


Function HookProc(nCode,wParam,lParam:Integer);Integer;stdcall;
begin
Result:=CallNextHookEx(OldHook,nCode,wParam,lParam);
end;

这样的话就完成了对进程的挂钩。可是挂上钩我们的工作并没结束,相反,我们的工
作才刚刚开始。钩子的作用是帮我们把DLL注入到别人的进程空间。现在我们的DLL已
经在别人的进程空间内。所以,我们就可以做我们想做的事。


下面介绍一下Windows的子类化处理。

大家都知道,在windows里不管你做了什么事,都会向windows发送一条消息,然后由
Windows作出相应的处理后才会返回给传送消息的应用程序。
那大家会问:“HOOK不是已经拦截了windows消息了吗?”

是啊,那也要看是拦截了什么消息,就如上面我们写的WH_KEYBOARD,我们拦截了键盘
消息,我们可以在按下任何一个按键的时候做出处理。消息的种类有很多。
可是我们今天要讲的是windows的子类化处理,这又是一门新的技术。
不废话了,这就开始。^_^

相信大家都见过两这个API:GetWindowsLong 和 SetWindowLong;
可能你们会说,这些不是处理窗口消息的吗?对,这就是我们要用到的API。

接下来让我们看一下这些API的参数。
LONG GetWindowLong(
HWND hWnd, //窗体的句柄
int nIndex //欲取回的信息,可参照下表
);
nIndex的值可以是下列任何一个
GWL_EXSTYLE 扩展窗口样式
GWL_STYLE 窗口样式
GWL_WNDPROC 该窗口的窗口函数的地址
GWL_HINSTANCE 拥有窗口的实例的句柄
GWL_HWNDPARENT 该窗口之父的句柄。不要用SetWindowWord来改变这个值
GWL_ID 对话框中一个子窗口的标识符
GWL_USERDATA 含义由应用程序规定
DWL_DLGPROC 这个窗口的对话框函数地址
DWL_MSGRESULT 在对话框函数中处理的一条消息返回的值
DWL_USER 含义由应用程序规定


也许大家会注意到 GWL_WNDPROC 这个参数。没错,我们子类处理就是要用到这个参数。
代码如下:
OldProc:=GetWindowLong(hWnd,GWL_WNDPROC);

这样我们的OldProc就指向窗体的窗口函数地址;
既然得到了窗口函数地址,那么就修改到我们自定义的消息处理地址里吧。
下面要用到SetWindowLong函数了。
LONG SetWindowLong(
HWND hWnd, //指定窗口句柄
int nIndex, //和GetWindowLong的nIndex一样
LONG dwNewLong //新的消息处理地址
);

代码如下:
SetWindowLong(hWnd,GWL_WNDPROC,Longint(@WinProc));

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:我观MIDAS

下一篇:新世纪的五四运动:程序白话文(1)