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

用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编制钩子函数有多么容易。最后不得不提醒大家:钩子函数虽然功能比较强,但如果使用不当将会严重影响系统的效率,所以要尽量避免使用系统钩子。非要使用不可时也应该格外小心,应使之尽可能小地影响系统的运行。

用VB读取和控制Windows的中文输入法 用VB将命令行软件Windows化 用VB进行移位操作 用VB开发CAI软件的小经验 用VB开发分布式应用 用VB切换三个特殊键 用VB生成EXE文件后,如何在后面加上参数?这个参数怎样传给VB 用VB实现动态显示操作进度程序 用VB实现双向循环链表 用VB实现用户登录密码的修改 用VB与MS-Draw开发通用作图软件 用VB制作TopMost类型窗口 用VB制作Windows风格安装盘 用Visual Basic 6创建基于MTS的商务组件 用Visual Basic实现Windows的重启动 VB用Windows管理技术做你的应用程序 VB用程序给标识字段(ID)赋值的一种简单实现方法 VB用自己的&#39;PROGRAM&#39;测试自己的电脑 有 BitMap 之Menu -VB资料 运行其他程序,并等待执行完毕 -VB资料 再谈VB程序的加密 在 VB 程序中如何设定 Mouse 光标的位置? 在ActiveX DLL工程中慎用App对象-VB资料 在ActiveX控件工程中设置DataField属性-VB资料 在VB中异步执行程序 在VB编程中有效地组织和利用资源 在VB应用程序中巧用DLL 在VB应用程序中使用INI文件的一点体会 在VB中操纵OLE服务器应用程序 在VB中改变显示器的分辨率 在VB中获取和修改计算机名字 一个表单里面有两个select下拉菜单选择项,一个是父类项一个是他的子类项,每一项都从库里提出来,问每选择一个父类项,下面的下拉菜单的子类 请问如此时间按纽是怎么做的?高手帮忙? 谁有比较好的数字信号处理的界面框架,给我发送一个 smart attribute check(failed) 200分都给你!谁能列出最好的几本算法与数据结构书,并提供下载地址? 菜鸟问题 各位高手,这个复制的存储过程要怎样写啊? 怎么把自己的图片做成asp的底板图? 请问在DELPHI中编程怎样打开WORD,EXCEL,。TXT文件并使他们可见?(谢谢) 小女子问一个很小很小的问题。举手之劳 好不容易才找到ACTIVE SKIN4.27的破解机 JDK文档 1000分都给你!谁能列出最好的几本算法与数据结构书,并提供下载地址? 请教一个问题~~~~~~!在线等~! 1000分都给你!谁能列出最好的几本算法与数据结构书,并提供下载地址? 1000分都给你!谁能列出最好的几本算法与数据结构书,并提供下载地址? 请问sql server 2000数据库 的unicode->big5如何转换? 倒分揭露 vc我自建了一个子窗体类,点击主窗体时显示,怎么做啊? 难道我的word文档全都废了吗?? 帮帮忙!一个小问题!呵呵! "自助建站系统"到底能不能实现真正的二级域名、独立域名? 请看看我的代码有什么问题 如何将一个OLE对象转换为位图(注:不要截屏的方式) 在olecontainer里面调出的excel文档,如何使之不可编辑。 急救啊!这个字体怎么设置? 请问在jcreator下能不能编译成exe啊? small_wei进来领分! 初学这样的,觉得是很简单的思路,但找不出错误,有经验的帮忙看看 if a sql syntan can succeed in sql but asp... GDI+的问题 谁有FLASH的注册码,给个,谢谢 怎样用js写一个终止程序,类似asp的response.end 求教:学习MFC文件系统-针对一段代码的3个初学者问题 如何使98一开机就运行屏保!!!急!!!来者有分!帮忙了!!!!! 怪问题 <了解Struts1.1 > 我刚看到的一篇好文章,贴出来,大家共享 dayday up (: 如何驱动8139网卡(笔记本) interbase能与VC结合吗?另外想问有些软件与interbase一起打包安装,如何实现的呢? Lotus——你在哪里? 网络编程中遇到的几个问题(求助) 在java中调用javac.exe 紧急在线等待,求助!!!!! 我是新来的,很多都不懂!也没有朋友,有谁能和我做朋友么? 分手为什么只要一个人说了就算,为什么不能像离婚一样要双方同意,法院判决??? 关于从TImage继承创建自定义控件的问题? JRUN4怎么运行Servlet? 关于远程创建表,删除表的问题?请帮忙。 启动数据库时报 监听程序无法启动专用服务器进程???ORACLE 9.2.0.1.0 如何將指針作為參數傳遞。 请教vb自带的报表编程 蛔虫体细胞不具有的细胞器?中心体,内质网,线粒体,核糖体,细胞核,高尔基体 大学英语六级成绩查询帮我查一下,212320092205323的成绩,谢谢了. 求《孙子兵法》以迂为直的意思最好举个例子. 蛔虫体细胞高尔基体膜能否无氧呼吸? I'm sorry!my dear!I shouldn't loss you 迂是什么意思 大众明星应该承担和履行哪些社会责任 i loss you 美国农业机械化对环境有什么影响 为什么陈独秀没有参加中共一大 My dear ,I don't wanna loss you 美国和澳大利亚农业机械化程度高,是因为什么自然因素? 陈独秀没有参加中共一大会议为什么被选为中共委员书记 you are my loss,while I am your irrelevance的中文意思 为什么农业机械化程度越高,成本会越低 literary figure是什么意思 The loss of all 、you never left my 用恰似造句 western literary theories是什么意思 在直角梯形ABCD中,AD//BC,角B=90度,AD+BC<CD,若腰CD上有一点P,使AP⊥BP,这样的点有几个?我还 没学圆的知识 ,请各位给我详细讲讲这道题,详细的我一定给分 恰似造句 关于蛔虫的线粒体蛔虫没有线粒体,寄生生活,那么他是无氧呼吸?还是直接从人体内获得能量?寄生生活是不是吸取营养物质吗?跟能量有么关系? 落叶离花岁无情.化做春泥更护花. pass “娱乐明星或科学家谁可以成为大学生的榜样?”辩题求给出正反方的辩论材料 描写一种动物捕食的情形!答出来的我超级感谢他拉! pass by可以理解为忽视吗? 陈独秀未参加中共一大,为什么当选中央局书记 (3)屈原至于江滨,被发行吟泽畔,颜色憔悴,形容枯槁.(《屈原》)/(5)师者,所以传道受业解惑也.(《师说》)/7)明日,徐公来,孰视之,自以为不如;窥镜而自视,又弗如远甚.(《邹忌》) 背景中"迂"是什么意思 literary savant是什么意思 中共“一大”选举陈独秀担当中央局书记的原因是什么? 现在最大的食肉植物有多大,能捕获什么样的动物? Literary appreciation 翻译成中文, (一个历史问题)陈独秀没有出席中国共产党第一次全国代表大会,为什么被选为中央局书记? 液压系统 DT表示啥意思详细点 literary figures 什么意思? 落叶不是无情物,化作春泥更护花 想纠正英语口语口音,cec英语是不是纯外教授课的,改善效果怎样 literacy啥意思?和literary有关系吗?英语 陈独秀没有参加中国共产党第一次全国代表大会,为什么还被选为中央局书记? 谁能详细说明一下cec的英语外教来源我要有关cec的详细的外教来源 因为先找个好点的英语培训班 正好看上cec 辩论:崇拜明星好不好?急用,我是反方4辩.不要灌水! 陈独秀没有出席中共一大为什么会被选为中央局书记 CEC电话英语外教一对一 新闻英语:“贸易失衡”怎么说为期两天的二十国集团首尔峰会昨晚正式开幕.但是由于各国之间意见分歧较大,很难在除经济合作承诺外达成其他共识.二十国集团希望 水生生物学属于理学还是农学 已知a-c=2,b-c=3,则a+b-2c=___ cec英语是外教一对一,那都和我们聊些什么呢,每天多长时间的通话 综合实践活动教案包含哪些? 已知a/2=b/3=c/4,求a+b-c/a+2c. (我需要过程.详细一点的,谢啦) 寻求一个cec英语之商务英语的外教视频,谁有的, 农学能不能转理学 当a+c=2.b+c=3那a+b+2c 写一篇关于你最喜欢的动物的英语文章.我喜欢狮子 急急急急急急急急急急急急急急!快 literary classic pass in english这句话对不对in English是不是做了谓语,介词短语是不是不能做谓语的? 帮忙找个道德榜样要现在在世的,起码要有点名气吧,不能虚构的.再举出一个他的故事或例子 上海话“搓克,刮三,昂三” 美国农业机械化程度很高,但在发展的过程中也会对环境造成危害,请列出几例 瑞士一战机在该国中部坠毁 人员伤亡未瑞士一战机在该国中部坠毁 人员伤亡未日媒:日将实施自卫队夺岛演习 或刺激三星向中国消费者道歉 7款问题机型将外交部:中印签署边防合作协议有利于巩联合国难民署高专:慷慨的叙利亚人民理外交部:日方无论采取何种手段都无法改外交部:中印签署边防合作协议有利于巩中国西部对欧洲国家吸引力增强高铁建设将带动泰国二线城市房价上涨金华开展消防排查整治行动 整改火灾隐浙江遂昌一男子为谋私利 盗挖珍贵植物第十七届宁波国际服装节:展东方品牌魅外媒:中国正“秘密”储备黄金 西方大中新论坛:中国需转变发展方式 避免中莫斯科将优化投资环境吸引私人投资普京称筹备第二次日内瓦会议是外交共同乔治小王子洗礼袍仿1841年维多利亚普京称筹备第二次日内瓦会议是外交共同乔治小王子洗礼袍仿1841年维多利亚澳洲青睐中国游客 维多利亚州长在沪“车陂北及时扑灭马鞍山火患生硬的“跨门槛经营”广氮社区百多户居民告别缺水求真务实 标本兼治 整改成效接受群众南充一嫌犯驾中巴撞入法院、交警大队全省21地市联通3G网络大升级省政协召开第12次主席会议动力电池生产线在湘投产麦当劳指大众点评网半价团购虚假井盖上的漂亮涂鸦雨湖区《民情走访本》融合干群心民生政策一定要体现雪中送炭禁养区,截断湘江养殖污染曼联造访儿童医院 莫耶斯偶遇“小兄弟国安上下为斯塔诺庆生40岁 朴成领唱举行第17次主任会议媒体总结民主生活会高频词:“调研形式苏宁集团董事长张近东入室盗窃案多发 派出所将“吃”红牌工博会下周开幕我省多措并举治雾霾
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘