说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

用DELPHI编制Windows95下的钩子函数

HTML文档下载 WORD文档下载 PDF文档下载
用DELPHI编制Windows95下的钩子函数

Windows消息管理机构提供了能使应用程序访问控制消息流μ

'c4所谓的钩子(HOOK)机制。钩子有多种,分别用于捕获某一特定类型或某一范围的消息。如:键盘消息,鼠标消息等。我们这里仅以键盘钩子的使用为例,讨论在DELPHI下怎样编写DLL程序和怎样在自己的程序中安装使用键盘钩子函数,并讨论了不同程序使用同一DLL文件时怎样共享数据。

一、 钩子过滤函数的编写说明

由于钩子过滤函数必须在独立的模块中,也就是说我们必须首先生成一个DLL框架,然后再在其中加入钩子函数代码以及其他相关函数代码。我们这里以键盘钩子过滤函数的编写为例来说明。具体步骤如下:

1、先生成一个DLL筐2架

2、编写自己的键盘钩子过滤函数

钩子过滤函数必须是回调函数,其函数的 4稳缦拢o

function KeyHookProc(

iCode:Integer;

wParam:WPARAM;

lParam:LPARAM ) : LRESULT; stdcall ;export ;

在生成的DLL框架中加入自己的键盘钩子处理函数处理键盘消息。

代码如下:…

if(iCode>=0) then begin

Result:=0; //初始化返回值

// 在这里加入自己的代码

end else

begin

Result:=CallNextHook(hOldKeyHook

iCode

wParam

lParam);

// hOldKeyHook是保存的原键盘过滤函数 5刂·

end;

3、 安装键盘钩子过滤函数

为安装一个钩子筥fd滤函数应调用SetWindowsHookEx函数(适用于Windows3.0的SetWindowsHook钩子安装函数现在已经废弃不用)。该函数的原形如下:

HHOOK SetWindowsHookEx(

int idHook

// 安装的筥b3子类型

HOOKPROC lpfn

// 钩子过滤籂f数地址

HINSTANCE hMod

// 任务句柄

DWORD dwThreadId // 钩子用于的目的

);

需要说明的是:蚠a8常应该调用MakeProcInstance函数以获取一个输出函数的前导码的入口地址,再将此地址作为SetWindowsHookEx的第二个参数lpfn。但由于Delphi提供了"灵巧调用(smart callback)",使得MakeProcInstance可以省去,而直接将钩子过滤函数名用作入口地址。

这样当应用程序觃c3GetMessage或PeekMessage函数从消息队列中读消息或有按键消息(WM_KEYDOWN或WM_KEYUP)要处理时,系统就要调用钩子过滤函数KeyHookProc处理键盘消息。

4、 卸载钩子过滤函数。

当钩子函数不再需要时,应调用UnHookWindowsHookProc卸载安装的钩子以释放系统资源。

完整的程序清单如下ba

Library KEYHOOK;

uses Windows;

const BUFFER_SIZE=16*1024;

const HOOK_MEM_FILENAME='SAMPLE KEY_HOOK_MEM_FILE';

const HOOK_MUTEX_NAME ='SAMPLE KEY_HOOK_MUTEX_NAME';

type

TShared=record

Keys : array[0..BUFFER_SIZE] of Char;

KeyCount : Integer;

end;

PShared=^TShared;

var

MemFile

HookMutex : THandle;

hOldKeyHook : HHook;

ProcSaveExit : Pointer;

Shared : PShared;

//键盘钩子过滤函数

function KeyHookProc(iCode: Integer; wParam: WPARAM ; lParam: LPARAM):LRESULT

; stdcall; export;

const KeyPressMask = $80000000;

begin

if iCode < 0 then

Result := CallNextHookEx(hOldKeyHook

iCode

wParam

lParam)

else begin

if ((lParam and KeyPressMask)= 0) then // 键按下

begin

Shared^.Keys[Shared^.KeyCount]:=Char(wParam and $00ff);

Inc(Shared^.KeyCount);

if Shared^.KeyCount>=BUFFER_SIZE-1 then Shared^.KeyCount:=0;

end;

iCode:=-1;

Result := CallNextHookEx(hOldKeyHook

iCode

wParam

lParam);

end;

end;

// 设置钩子过滤函数

function EnableKeyHook : BOOL ; export;

begin

Shared^.KeyCount:=0; //初始化键盘指针

if hOldKeyHook=0 then begin

hOldKeyHook := SetWindowsHookEx(WH_KEYBOARD

KeyHookProc

HInstance

0);

end;

Result := (hOldKeyHook <> 0);

end;

//撤消钩子过滤函数

function DisableKeyHook: BOOL ; export;

begin

if hOldKeyHook<> 0 then

begin

UnHookWindowsHookEx(hOldKeyHook); // 解除 Keyboard Hook

hOldKeyHook:= 0;

Shared^.KeyCount:=0;

end;

Result := (hOldKeyHook = 0);

end;

//取得键盘缓冲区中击键的个数

function GetKeyCount :Integer ; export;

begin

Result:=Shared^.KeyCount;

end;

//取得键盘缓冲区的键

function GetKey(index:Integer) : Char ; export;

begin

Result:=Shared^.Keys[index];

end;

//清空键盘缓冲区

procedure ClearKeyString ; export;

begin

Shared^.KeyCount:=0;

end;

//DLL的退出处理过程

procedure KeyHookExit; far;

begin

if hOldKeyHook <> 0 then DisableKeyHook;

UnMapViewOfFile(Shared); // 释放内存映象文件

CloseHandle(MemFile); // 关闭映象文件

ExitProc := ProcSaveExit;

end;

exports // 定义输出函数

EnableKeyHook

DisableKeyHook

GetKeyCount

ClearKeyString

GetKey;

begin

// DLL 初始化部分

HookMutex:=CreateMutex(nil

True

HOOK_MUTEX_NAME);

// 通过建立内存映象文件以共享内存

MemFile:=OpenFileMapping(FILE_MAP_WRITE

False

HOOK_MEM_FILENAME);

if MemFile=0 then

MemFile:=CreateFileMapping($FFFFFFFF

nil

PAGE_READWRITE

0

SizeOf(TShared)

HOOK_MEM_FILENAME);

Shared:=MapViewOfFile(MemFile

File_MAP_WRITE

0

0

0);

ReleaseMutex(HookMutex);

CloseHandle(HookMutex);

ProcSaveExit := ExitProc; // 保存DLL的ExitProc

ExitProc := @KeyHookExit; // 设置DLL新的ExitProc

end.

// 源代码结束

二、 在自己的程序中使用编制好的键盘钩子过滤函数。

钩子函数编制好后,使用起来其实很简单:首先调用SetWindowsHookEx安装自己的钩子过滤函数,同时保存原先的钩子过滤函数地址。这时钩子函数就开始起作用了,它将按照你的要求处理键盘消息。程序运行完毕或不再需要监视键盘消息时,调用UnHookWindowsHookProc函数卸载所安装的钩子函数,同时恢复原来的钩子过滤函数地址。

下面就是使用在以上编制的钩子函数的例子:

unit Unit1;

interface

uses

Windows

Messages

SysUtils

Classes

Graphics

Controls

Forms

Dialogs

StdCtrls

ExtCtrls;

type

TForm1 = class(TForm)

Memo1: TMemo;

Panel1: TPanel;

bSetHook: TButton;

bCancelHook: TButton;

bReadKeys: TButton;

bClearKeys: TButton;

Panel2: TPanel;

procedure bSetHookClick(Sender: TObject);

procedure bCancelHookClick(Sender: TObject);

procedure bReadKeysClick(Sender: TObject);

procedure bClearKeysClick(Sender: TObject);

end;

var Form1: TForm1;

implementation

{$R *.DFM}

function EnableKeyHook : BOOL ; external 'KEYHOOK.DLL';

function DisableKeyHook : BOOL ; external 'KEYHOOK.DLL';

function GetKeyCount : Integer ; external 'KEYHOOK.DLL';

function GetKey(idx:Integer) : Char ; external 'KEYHOOK.DLL';

procedure ClearKeyString ; external 'KEYHOOK.DLL';

procedure TForm1.bSetHookClick(Sender: TObject); // 设置键盘钩 7ó

begin

EnableKeyHook;

bSetHook.Enabled :=False;

bCancelHook.Enabled:=True;

bReadKeys.Enabled :=True;

bClearKeys.Enabled :=True;

Panel2.Caption:=' 键盘钩子已经设置';

end;

procedure TForm1.bCancelHookClick(Sender: TObject); // 卸载键盘钩子

begin

DisableKeyHook;

bSetHook.Enabled :=True;

bCancelHook.Enabled:=False;

bReadKeys.Enabled :=False;

bClearKeys.Enabled :=False;

Panel2.Caption:=' 键盘钩子没有设置';

end;

procedure TForm1.bReadKeysClick(Sender: TObject); // 取得击键的历史记录

var i:Integer;

begin

Memo1.Lines.Clear; // 在Memo1中显示击键历史记录

for i:=0 to GetKeyCount-1 do

Memo1.Text:=Memo1.Text+GetKey(i);

end;

procedure TForm1.bClearKeysClick(Sender: TObject); // 清除击键历史记录

begin

Memo1.Clear;

ClearKeyString;

end;

end.

// 源代码结束

三、 Windows95下DLL中实现共享内存

在上面的钩子函数所在的DLL文件中,需要使用共享内存,即,所有击键的记录存储在同一个数据段中。为什么要这样做呢?这是因为Windows95的DLL调用方法与Windows3.X的方法不同。每个进(线)程在登录某动态连接库时都会为该动态连接库传入一个新的实例句柄(即DLL数据段的句柄)。这使得DLL各个实例之间互不干扰,但是这对那些所有DLL实例共享一组变量带来一些困难。为了解决这个问题,我们在这儿通过建立内存映射文件的方法来解决。即使用Windows的OpenFileMapping、CreateFileMapping和

MapViewOfFile三个函数来实现。使用方法如下:

MemFile是THandle类型,Shared是指针类型,HOOK_MEM_FILENAME是一常量串

MemFile:=OpenFileMapping(FILE_MAP_WRITE

False

HOOK_MEM_FILENAME); //打开内存映射文件

if MemFile=0 then //打开失败则衉c2建内存映射文件

MemFile:=CreateFileMapping($FFFFFFFF

nil

PAGE_READWRITE

0

SizeOf(TShared)

HOOK_MEM_FILENAME);

//映射文件到变量

Shared:=MapViewOfFile(MemFile

File_MAP_WRITE

0

0

0);

到此为止,你已经知道用Delphi编制钩子函数有多么容易。最后不得不提醒大家:钩子函数虽然功能比较强,但如果使用不当将会严重影响系统的效率,所以要尽量避免使用系统钩子。非要使用不可时也应该格外小心,应使之尽可能小地影响系统的运行。

Intel携手三星、博通等 建立物联网联盟OIC 一周消息树:微软半年内将终止对Win 7、Office 2010 SP1等产品的支持 深度神经网络DNN的多GPU数据并行框架 及其在语音识别的应用 浪潮通软GSP将打造开放平台 吸引更多ISV加入生态系统 国外安全产品再遭信任危机 安全产品国产化步伐加快 最终幻想XIV的重生--SQUARE ENIX《最终幻想14》制作人吉田直树介绍 如何打造百万级自然增长的微信HTML5应用 听邵海杨聊聊1000+台服务器背后的故事 借助Facebook、Twitter等社交平台API打造超炫酷的那些应用 Unity中Shader的开发运用实战详解,开放报名! 我从独立游戏开发学到的6件事儿 果断Mark!Searchcode——源代码搜索利器 《近匠》图灵机器人:App和移动硬件的智慧大脑 极路由发布HiWiFi OS及应用开放平台 Loom SDK框架:命令行快速开发跨平台2D游戏 安全管家Q2移动安全数据报告:窃取隐私最多 Project Adam vs. Artificial Brain,微软与谷歌角力人工智能 “微信公众平台优秀开发商”征集评选活动正式启动 移动数据库新疆界:开源、Swift、可穿戴... Chromebook侵蚀微软商用PC市场,成绩喜人 2014微信开发者大会议程公布 8月1日前购票8折优惠并赠书 四火的唠叨:也谈谈全栈工程师 图形化与集成趋势 协同软件致远发新品V5.1 跨平台开发如何事半功倍 Xamarin推出免费培训 《近匠》上海庆科:海尔智能家居背后的云方案 轻松DIY智能硬件,开源电子原型平台Hippo-ADK 所见即所得!基于Polymer的设计工具Mobile UI Elements 好的产品经理是怎样炼成的? 统一架构、统一运维:UnitedStack发布UOS2.0 把轻应用带进汽车——宝马、百度编程马拉松大赛启动 “钢铁侠”Insteon的逆袭:声控智能家居新时代 用CSS可以改变table中的字体颜色吗? 在delphi中怎样注册一个ocx控件,用代码如何实现!!! 如何找到文件? 請問怎樣知道SQLServer里IMAGE字段是否為空 救命啊!开发gis系统需不需要后台数据库 散装赛扬III配的原装Intel风扇的问题 急!!!百分求解window api中CHOOSEFONT与LOGFONT关系。 问一个vc中CRecordset定义问题 怎么通过程序改变REMOTEDATACTL的属性? 请问如何在JSP中实现邮件的收发?(涉及到密码验证的问题)我已经郁闷很久了! 如何得到另一个进程中的线程正在使用的tcp/ip端口? **好像有一个网址可以自由上传30M以下的软件,请问有谁知道这个网址?????** Unicode的问题???? db 库文件被破坏,请教高手? 本人刚接触vc,紧急求助! 请问,如何将简体字的网页,转换为繁体字的网页? 请教vb3秒精确定时问题? 哪位大侠能在今天内急救!!关于asp.net的数据验证和数组传送问题 lihonggen0(李洪根,用VB,标准答案来了) 密码被人盗用 在Delphi中用ADO怎样连接Excel表 x++等的问题。 当一个数据库数据更新后如何通知所有连接到此数据库的用户来更新自己? 一个有趣的问题 奉献100, 现在手头有个程序,关于附件上传! 如何判断A字符串中是否包含B字串? 做个类似的邮件发送程序 快快就我 怎样同时新增主从两张表的数据? vb.Net中的几种类型集合中,那种适合于用Index和Key来索引?我怎么觉得.Net的CollectionBase还没有vb6的Collection好使? 为亚洲雪耻,为中国队加油!! 紧急求助:在那儿可以找到关于字体文件的文件格式!!! 测试adoconnection是否已关闭 请教各位大侠! 关于表设了密码的问题 开始了吗?开始了吗?北京的高程考试报名开始了吗? 如何自定义数据类型? 图片显示不了了 java 线程,对当前线程(非主线程)调用sleep,为什么主线程(窗口)也没反应了 各位大虾帮忙呀,哪位把下面的文字翻译成准确的英文,200分相赠!!!决不食言!!! 请教:PHP下的事件处理方法 如何通过ASCII码区分全角与半角字符?急! 触发器???:(拜托各位大哥大姐,大叔大伯! 字符串替换函数是什么? 送分 那位大虾帮我翻译一下 急 分不够可以加 为了忘却的纪念! 急急急急急!!!!!!!!!!,Band里的内容过长,如何让它自动的分页??? oicq的窗口title怎么为空了?如何得到句柄? session问题! 用dbgrideh控件,如何实现汇总结果的打印 有关ATL的最基础问题 怎样监控icmp包?用自编的程序 北极的极昼期是? 北京4月的时候,北极是极昼还是极夜 什么叫等容过程?等容过程中吸收的热量和所做的功如何计算? 名词解释音节是什么 化学实验——蒸馏,这一过程中一定要使用温度计吗?为什么 热力学第一定律说吸收的热量转换为内能和对外做的功.如果定容加热,做功为0,内能和和压力势能都增加? 水为什么可以腐蚀不锈钢? 求关于水的作文,600字,急. 1mol任何物质均含有6.02X10的23次方个微粒 卡诺循环中怎么对外界做功的? 初三物理什么是动能和什么是势能求教,.急 关于水的600字作文,急用! 冷却水有什么作用? 跳伞运动员在空中匀速下落是是能转化为动能吗? 有关水的600字作文尽快啊 我现在就要 足量氯气与溴化亚铁反应的方程式怎么写? 初三物理(动能和势能)跳伞运动员从高空的飞机跳下后,在降落伞尚未打开之前的下落过程中,运动员的动能________,重力势能__________.当降落伞打开,运动员匀速下落时,他的动能(),重力势能 生命与水 论文600字左右写出不良现象和节约方法 写出节约水源标语和标志同志们速度!急啊! 如何制作过冷却水?不要百度百科上的. "焦"是什么单位?好像和热量有关,但是怎么书上说 1焦=1牛*米 到底是功的单位还是热量的单位?如果都是,有什么关系?说清楚一些,但不要太深了, 硫酸铜固体与铁钉反应吗? 过冷却水怎么做越简单越好 一个大杯和一个小杯共43元,并且两个大杯和3个小杯共94元,可知一个杯子多少元,方程 如何判断铁钉加入硫酸铜溶液后反应完全 什么实验证明大气压强值 关于热量,功,内能的概念,下列说法正确的是() A.热能,功,内能的国际单位都是焦,所以三者的物理关于热量,功,内能的概念,下列说法正确的是()A.热能,功,内能的国际单位都是焦,所以三者 化学反应 需要温度计有哪些 液体压强实验有实验器材:水,一个大水槽,足量的细沙子,平底试管.设计一个实验证明:当液体密度保持不变时,液体内部的压强,与液体的深度成正比.写出主要的实验步骤 《画菊》郑思肖 的读后感50字 哪些化学反应要温度计RT 我要大气压强的实验数据 测定化工产品的物理参数为什么可以反映化工产品的质量 需要把温度计放入溶液中的化学反应 动能定义:物体由于运动而具有的能那么应该是说明运动是产生这种能的原因请问这是为什么? 动能与势能的理解与计算公式还有动能和重力势能公式中的Ek和Ep是什么意思 摩擦做功产生热量分配问题产生的热量是两个物体平均分配吗,还是怎样分? 有大,小两只,把8杯水倒入空的大杯中,水占大杯容积的5分之4,那么1小杯水占大杯 请问什么叫音位啊?跟音素 音节有什么区别啊?好崩溃! 汉语拼音zhuang的音节音序! 大型溴化锂制冷机 冷冻水进出口压力 最高是多少?我公司用的是大型溴化锂制冷机组 冷冻水流量500吨/小时.平时工作压力:冷冻水进口5公斤 出口4公斤这种机组蒸发器铜管能承受多大压力?铜 汉语音节ban、da、guang中的a,是三个不同的音素,但却是同一个音位,为什么?语言学相关知识解释. 作文 这是一种幸福(500字)快来不及了! 内能为什么会转移?曾听说是因为存在温度差,这太笼统了,期待你的答案.能否精确到分子概念! 氢氧化钠与氯气反应有时生成次氯酸钠,有时生成氯酸钠.问什么时候生成次氯酸钠,什么时候生成氯酸钠? 汉语的拼音中,什么是音序?什么是音节?例如:拼音 zhu 声调为四声; 拼音 cheng 声调为二声. 以上两个例子都怎么来描述它们的音节和音序分别是什么? w是内能的单位吗 冬季哥本哈根为什么刮西南风 拼音查字典时音节是什么?音序是什么? (动能与势能)历史上曾有记载,印度的一架客机曾与一只鸟相撞,造成机毁人亡的惨剧,解释下为什么... 为什么赤壁之战中明明冬天没东南风都来怎么又刮东南风的 郑思肖的画菊的内容情景和精神品格 北极点的极昼一年有几天?我想知道在北极点上有多少天不出太阳?多少天太阳不落?最好告诉我是从那一天开始到哪一天结束,一共多少天.十万火急 不管是东南风,还是西南风,都是我的歌、我的歌.这首中国民谣里面的西北风和东南风指的是?A、龙卷风 B、台风 C、飓风 D、季风 为什么桑拿室里温度高达90度100度却伤不着人?医学上有理论 蛋白质六十度就会变质 那么桑拿室里的温度到达90度甚至100度却又如何解释 《语言学概论》作业 一、 语言学 组合关系 聚合关系 音素 音位 音节 语流音变 同化异化 元音 《语言学概论》作业一、 语言学 组合关系 聚合关系 音素 音位 音节 语流音变 同化异化 元音 当北极出现极昼 海南的白昼长还是漠河的,反之当南极出现极昼的时候哪个城市白昼长?如果是极夜 哪个城市黑暗长 冰柜换上压缩机后,头三天结霜正常,使用后不结霜,反而结冰,排气管温度过高,高达100度,这是为什么 汉语言学中 音节 音素 语素 如题 再分别举例说明 最好用同一例子来具体说明~如果有儿化音 比如“冰棍儿”这时 音节 音素 语素 各有几个 怎么划分 现代汉语中有什么方法能快速准确地确定一个音节中的音素个数? 有机玻璃和聚碳酸酯,是什么关系?
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘