用Delphi实现Windows的鼠标钩子函数

Delphi是基于PASCAL语言的Windows编程工具,功能十分强大。然而在Delphi的帮助
文件中,对Windows API函数的说明沿袭了 VC 的格式,和VC一样,对很多API函数的用法
没有举例子详细说明,对一些深入系统内部的API函数更是语焉不详,给编程者带来不便。
笔者仅就在Windows编程中鼠标钩子函数(HOOK)的实现,举例作一说明。
   鼠标钩子函数也可叫做鼠标消息过滤器,是一种回调(CALLBACK)函数,归
系统调用。如果用SetWindowsHook或SetWindowsHookEx安装了鼠标钩子函数的地址, 每
当在屏幕上移动鼠标时,系统便将控制权交给鼠标钩子函数,这样便使我们能够有机会在
鼠标钩子函数内部截获各种鼠标消息,在这些消息还没有送达应用程序队列之前,显示它
们,改变它们或直接传给下一个缺省鼠标钩子函数。注意,鼠标钩子函数截获的是系统级
消息,而不是单个应用程序队列内的窗口消息;系统发给每个应用程序队列的鼠标消息都
可以用鼠标钩子函数来截获。
    VC的Spy和Delphi的WinSpy均安装了钩子函数用来截获各种系统级的消息,其中就
包括鼠标钩子函数,键盘钩子函数,窗口钩子函数等。我们可以通过安装鼠标钩子函数来
仿制一个自己的SPY,当鼠标移动时,我们立即获得系统(包括非抢先的Windows3.1和
抢先Windows95)的控制权,在鼠标钩子函数内部实时地截获鼠标消息,显示鼠标的位置
和状态以及鼠标下窗口的局柄,标题栏,窗口类,窗口过程地址等。当然也可象“英汉通”
和“金山词霸”一样在鼠标钩子函数内调用InvalidateRect(),InvalidateRgn()来获得屏
幕上鼠标下的单词。(屏幕抓字的详情请见笔者的《深入Windows内部探险》中国计算机报
1998年第81期 )。
   
    主程序SPY及其动态连接库MOUSEDLL的原代码和详细注释如下:
{*****************************************************
 FILE   :  MOUSEDLL.DPR   [email protected] 1998/11/18
 〉DLL  :  MOUSEDLL.DLL
 EXPORT: sethook      用来安装鼠标钩子函数 mouseproc
         unhook       解除对鼠标钩子函数 mouseproc的安装
         mouseproc    鼠标钩子函数本身
 *****************************************************}
library Mousedll;

uses
  Mousep in ‘MOUSEP.PAS‘ {Form1};
exports
sethook,
unhook,
mouseproc;
{$R *.RES}
begin
end.

{*************************************************************
 file:Mousep.pas                      [email protected]
 实现 setHook  unHook mouseProc 3个输出函数
 *************************************************************}
unit Mousep;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls;

{在DLL中也可有FORM型的变量}
type
  TForm1 = class(TForm)
    Label1: TLabel;  {显示wParam}
    Label2: TLabel;  {显示lParam}
    Label3: TLabel;  {显示x,y}
    Label4: TLabel;  {显示hwnd}
    Label5: TLabel;  {显示window text}
    Label6: TLabel;
    Label7: TLabel;  {显示window class}
  private
    { Private declarations }
  public
    { Public declarations }
  end;

function sethook:bool;export;
function unhook:bool;export;
function mouseProc(code:integer;w:integer;l:longint):bool;export;

var
  Form1: TForm1;
  idhook:longint;
  formok:bool;
implementation
 {*********************************************************************
 声明安装函数setWindowsHookEx(),
 在Delphi中如果用函数setWindowsHook()则不需声明。
 微软说函数setWindowsHook已在Windows3.1中废弃,为与Windows3.0兼容仍保留。
 实际上该函数setWindowsHook在Windows3.1和Windows95中仍可使用。
 {*********************************************************************}
 function setwindowsHookEx(id:integer;proc:tfarproc;hinst,htask:thandle):
         longint;far;external ‘user‘;
{$R *.DFM}

{安装鼠标钩子函数mouseProc}
function sethook:bool;
var
hinst:thandle;    {该动态连接库自己的模块局柄}
proc:tfarproc;    {鼠标钩子函数mouseProc的地址}
begin
{在动态连接库中创建form1}
if formok=false then form1:=tform1.create(application) else exit;
formok:=true;{安装form1 后,设置formok,不许再安装form1}
{动态连接库的application指:调用动态连接库的主程序}
form1.show;

{不让用系统菜单来双击关闭Form1}
form1.BorderIcons:=form1.BorderIcons-[biSystemMenu];

hinst:=getModuleHandle(‘mousedll‘);
{得到mousedll.dll的模块局柄,即该动态连接库自己的模块局柄}

proc:=getProcAddress(hinst,‘mouseProc‘);
idhook:=setWindowsHookEx(WH_MOUSE,proc,hinst,0);
{用WH_MOUSE参数安装鼠标钩子后,移动鼠标时,系统自动调用mouseProc钩子}
if idhook =0 then sethook:=false else sethook:=true;
end;

{解除鼠标钩子函数mouseProc的安装}
function unhook:bool;
begin
if formok=true then form1.free else exit; {检查form1是否已经关闭}
formok:=false;{关闭了form1,设置formok=0}
if idhook=0 then exit;
unhookWindowsHookEx(idhook);
unhook:=true;
end;

{mouseProc不由应用程序调用,而是在鼠标移动后,由系统调用}
function  mouseProc(code:integer;w:integer;l:longint):bool;
var
p:^TMouseHookStruct;
poff:word;
pseg:word;
pmemo:pchar;
begin
if code<0 then begin
    mouseProc:=true;
    CallNextHookEx(idhook,0,w,l);
end;
if code=HC_NOREMOVE then form1.caption:=‘HC_NOREMOVE‘;
form1.caption:=‘mouse hook‘;
mouseProc:=false;
{显示系统传来的wParam参数,w是各种鼠标消息的标识符  }
form1.label1.caption:=‘wParam=‘+intTostr(w);
{显示系统传来的lParam参数,l是MOUSEHOOKSTRUCT结构的地址}
form1.label2.caption:=‘lParam=‘+intTostr(l);

poff:=loword(l);     {得到l的低16位}
pseg:=hiword(l);     {得到l的高16位}
p:=ptr(pseg,poff);   {合成指向MOUSEHOOKSTRUCT结构的指针}

{显示屏幕上鼠标的X,Y坐标}
form1.label3.caption:=‘pt.x=‘+intTostr(p^.pt.x)
     +‘  pt.y=‘+intTostr(p^.pt.y);
{显示屏幕上鼠标下的窗口局柄}
form1.label4.caption:=‘hwnd=‘+intTostr(P^.hwnd);

pmemo:=stralloc(20);
getWindowText(p^.hwnd,pmemo,20-1);
{显示鼠标下窗口的标题栏}
form1.label5.caption:=strPas(pmemo);

getClassName(p^.hwnd,pmemo,20-1);
{显示鼠标下窗口的类}
form1.label6.caption:=strPas(pmemo);

strDispose(pmemo);

end;
end.

主程序原代码如下:
{*******************************************
 MAINTRY.DPR               [email protected]
 ******************************************}
program Maintry;

uses
  Forms,
  Tryp in ‘TRYP.PAS‘ {Form1};

{$R *.RES}

begin
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

{*********************************************
 TRYP.PAS                    [email protected]
 ********************************************}

unit Tryp;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;       { 安装setHook按钮}
    Button2: TButton;       { 解除 unHook按钮}
    Label1: TLabel;         {显示安装,解除是否成功}
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
function sethook:bool;far;external ‘mousedll‘;
function unhook:bool;far;external ‘mousedll‘; 
  {声明后自动加载模块mousedll.dll}
{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
if sethook then label1.caption:=‘set hook ok‘; {安装鼠标钩子函数}
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if unhook then label1.caption:=‘unhook ok‘;    {解除鼠标钩子函数}
end;

end.

http://blog.csdn.net/diligentcatrich/article/details/6934092

时间: 2024-08-05 09:48:35

用Delphi实现Windows的鼠标钩子函数的相关文章

Windows下设置钩子函数

当用户在window下操作时,钩子函数可以根据你的设置勾取window的操作消息 1.定义钩子函数 HWINEVENTHOOK hook = SetWinEventHook( _eventMin, _eventMax, NULL, WinEventProcSTATIC, 0, 0, WINEVENT_OUTOFCONTEXT); 2.撤销设置的钩子 UnhookWinEvent(hook); 3.钩子事件处理函数 void ProcessForgroundMonitor::winEventPro

Delphi的windows剪切板操作函数

1. Clipbrd函数 function Clipboard: TClipboard;:若应用程序从未使用过剪贴板,则调用该函数形成新的剪贴板:若之前使用过剪贴板则返回使用过的剪贴板. 属性: AsText:将剪贴版的内容作为一个字符串输出:方法:HasFormat:指示剪贴板中是否包含指定格式的数据.例如: [delphi] view plain copy procedure TForm1.Button1Click(Sender: TObject);beginif Clipboard.Has

HOOK API (一)——HOOK基础+一个鼠标钩子实例

HOOK API (一)——HOOK基础+一个鼠标钩子实例 0x00 起因 最近在做毕业设计,有一个功能是需要实现对剪切板的监控和进程的防终止保护.原本想从内核层实现,但没有头绪.最后决定从调用层入手,即采用HOOK API的技术来挂钩相应的API,从而实现预期的功能.在这样的需求下,就开始学习了HOOK API. 0x01什么是HOOK API HOOK(钩子,挂钩)是一种实现Windows平台下类似于中断的机制[24].HOOK机制允许应用程序拦截并处理Windows消息或指定事件,当指定的

VC6 鼠标钩子 最简单样例

Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的.而钩子是Windows系统中非常重要的系统接口,用它能够截获并处理送给其它应用程序的消息,来完毕普通应用程序难以实现的功能.钩子能够监视系统或进程中的各种事件消息,截获发往目标窗体的消息并进行处理.这样,我们就能够在系统中安装自己定义的钩子,监视系统中特定事件的发生,完毕特定的功能,比方截获键盘.鼠标的输入,屏幕取词,日志监视等等.可见,利用钩子能够实现很多特殊而实用的功能.因此,对于高级编程人员来说,掌

消息钩子函数入门

Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的.而钩子是Windows系统中非常重要的系统接口,用它 可以截获并处理送给其他应用程序的消息,来完成普通应用程序难以实现的功能.钩子可以监视系统或进程中的各种事件消息,截获发往目标窗口的消息并进行处 理.这样,我们就可以在系统中安装自定义的钩子,监视系统中特定事件的发生,完成特定的功能,比如截获键盘.鼠标的输入,屏幕取词,日志监视等等.可见, 利用钩子可以实现许多特殊而有用的功能.因此,对于高级编程人员来说

Delphi实现全局鼠标钩子

其中涉及到的一些API,网上均能查到详细的解释,这里不再熬述.源码下载 因为是全局钩子,所以要用dll注入.用到的鼠标消息结构如下: [delphi] view plaincopy PMouseHookStruct = ^TMouseHookStruct; {$EXTERNALSYM tagMOUSEHOOKSTRUCT} tagMOUSEHOOKSTRUCT = packed record pt: TPoint; hwnd: HWND; wHitTestCode: UINT; dwExtraI

利用钩子函数来捕捉键盘响应的windows应用程序

一:引言: 你也许一直对金山词霸的屏幕抓词的实现原理感到困惑,你也许希望将你的键盘,鼠标的活动适时的记录下来,甚至你想知道木马在windows操作系统是怎样进行木马dll的加载的…..其实这些都是用到了windows的钩子函数.因此本文将对钩子函数的相关知识进行阐述.当然,本文的目的并不是想通过此程序让读者去窃取别人的密码,只是由于钩子函数在windows系统中是一个非常重要的系统接口函数,所以想和大家共同的探讨,当然本文也对怎样建立动态连结库(DLL)作了一些简单的描述.(本文的程序为vc6.

php 钩子函数原理 解析

目前对钩子的理解:<转载:http://www.cnblogs.com/del/archive/2008/02/25/1080825.html> 譬如我们用鼠标在某个窗口上双击了一次, 或者给某个窗口输入了一个字母 A; 首先发现这些事件的不是窗口, 而是系统! 然后系统告诉窗口: 喂! 你让人点了, 并且是连续点了两鼠标, 你准备怎么办? 或者是系统告诉窗口: 喂! 有人向你家里扔砖头了, 不信你看看, 那块砖头是 A. 这时窗口的对有些事件会忽略.对有些事件会做出反应: 譬如, 可能对鼠标

钩子编程(HOOK) 安装进程内鼠标钩子

作者 : 卿笃军 钩子函数: WINDOWS的钩子函数可以认为是WINDOWS的主要特性之一.利用它们,您可以捕捉您自己进程或其它进程发生的事件.通过"钩挂",您可以给WINDOWS一个处理或过滤事件的回调函数,该函数也叫做"钩子函数",当每次发生您感兴趣的事件时,WINDOWS都将调用该函数. 下面介绍如何安装一个进程内的鼠标钩子. 第一步:打开VC6.0,新建一个基于对话框的MFC应用程序. 第二步:将如下代码拷贝到BOOL CInnerHookDlg::OnI