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

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

14岁少年开发者:伍兴云的智能家居“梦” Xcode 6 Beta 6发布闹乌龙,着重改进Swift语言 当API遇到云平台,开发者面临的新抉择! 《近匠》欧朋流量宝,工具类应用开发之道 《近匠》Bmob:免费无限制的公有云服务 MDCC应用征集最新动态:3D手游成热点、硬件种类丰富 闪迪Ultra II SSD:采用TLC闪存,最低价为79.99美元 现有技能不浪费!基于Titanium的跨平台游戏引擎Platino 跳过开发者,专注补Bug的iOS 8 Beta 6悄然发布 集群管理可以很简单,Google又放大招 应用内直接打车:Uber面向第三方开发者开放API 百万美元巨奖!英特尔启动感知计算挑战赛 IBM 2014技术峰会在京开幕! OpenGL 4.5规范标准发布,大大提升API性能! 更萌更贱:Flappy Bird开发者推虐心新作Swing Copters 学习的革命:AR增强现实遇到儿童应用 颠覆旧概念,IBM Bluemix开启云开发时代 专访企业QQ SaaS团队,谈企业级LNMP架构设计 《近匠》Coding:将软件开发搬到云上 小米与美视频游戏服务Ouya合作 进军国内客厅 新工具Get!轻松实现2D画面动态光影的Sprite Lamp 一周消息树:罗升阳的Android之旅 手游不易:GungHo 3.44亿美元售Supercell股权 周末去哪儿 当然是去2014微信开发者大会!(附参会提醒和名单) 开源框架Ember.js迎来1.7.0和1.8 Beta 1更新 《近匠》RealSense:几行代码,为游戏添增实感交互 MDCC游戏应用征集关键词:中小团队,3D,转型,IP 共话HealthKit:能否颠覆医疗保健生态系统? Perception Neuron系统,让动作捕捉技术不再高冷 2014年DevOps实践调查报告 .NET程序性能的基本要领 Women over 50 谁编个例程给我,这50分就是谁的了。题目不难,相信高手5分钟就能做完。 jdk1.3+jswdk1.0.1 的JAVAbeans .class文件要放哪啊????? God painted it 提问:猪真的很幸福吗?要求 wywq(幸福如猪) 回答。 哪位高手做过可视电话的? VB能不能实现“一个结构体类型的数组当参数传递 Forgotten Birthd Husbands Overheard Fine 有个在多线程中使用ADO的问题。请高手们帮忙。 Suede jacket 可能是installshield的Bug! 我想去北京找个工作,请大家帮帮忙,提供点信息! 装了“猫”为何还有630错误(电话线也接了)? excel 問題 各位:数据窗口有一检索变量,现在想retrieve出所有的记录,检索变量应该怎样赋值?谢谢! linux和windows是不是只能分别装在两个分区中 关于图像处理:如何使图像锐化与柔化? 帮帮我啦! 我在使用jdbc读取数据的时候,碰到了内存溢出的问题,怎么回事呀 哪里有餐饮系统的介绍?90不够的话,先欠着,多谢了! 在两个ASP程序之间怎么传递参数? ccl2000(不帅不酷的Goblin):其实你真的很酷很帅的。 大侠帮帮我啦(关于SQL语句的问题) 关于Vxd的编译问题 用VC编的程序,一运行就说“执行非法操作”,问题出在哪里?? SQL Server有病 一个关于api的简单问题 《易佳自定义报表》用后很失望 请教各位高手一个有关报表控件的问题? 小妹向大家请教!可不可以直接在本页的代码中改变该页面浏览时的属性? 家菲猫:惊悉你昨晚惨遭不幸,被窃大量钱物,今日一天无法和你联系上,估计手机和通信录已全部丢失,如果今晚无法来我处,明早8点以前请务必携猫 MM 赶到上海南站!!! MDI文档模板和应用程序调用问题请教,大侠请进! 一个c++问题???? 请问各位高手,sqlserver2k加密的存储过程是否能解密,看到它的实际的语句?可否能跟踪加密的存储过程? 我下载了一个formula one ,发现她的界面跟excel差不多,在pb中怎么用? 高分求XML 高级编程(足本)[01.pdf到10.pdf]!!!! 招聘汇编程序员 ie 中true dbgrid 的问题 急招聘汇编程序员 关于WINDONWS文件夹 WIN2000有关用户管理的问题 谁可以告诉我怎么调用已有的EXE文件。 有谁知道广州或南海的高级程序员考试的辅导点 如何把系统时间作为一个文件的保存名? TURBO C语言对磁盘操作的问题 着急招聘汇编程序员 为什么大家得的都是0分? 这行代码是什么意思: 不知怎的,不小心访问到一个网站。我已设为使用空页,可它还是要先启动,画面又恶劣,怎么办? 溴水加入到直馏汽油这个会发生反应吗.发生反应是使溴水褪色么..还是说他们是萃取的关系... 常减压蒸馏产品质量调节 高二化学知识点总结 裂解和裂化哪个是深度裂化 加氢裂化工艺提供商 A、B、C、D、E均为可溶于水的固体,组成它们的离子有:阳离子:Na+、Mg2+、Al3+、Ba2+阴离子:OH-、Cl-、碳酸根离子、硫酸根离子、硫酸氢根离子分别取其水溶液进行试验,结果如下:①A溶液与B 环烷烃是不是饱和烃?如果是,为什么他有一个不饱和度? 加氢裂化过程主要发生哪几种化学反应? 热方程式的加减怎么个加减法?是否可以据一些例子? 链状烷烃叫烷烃?环状烷烃叫环烷烃? 松花蛋的制作过程中所发生的化学反应 已知在298K时下列反映的有关数据:C(s)+1/2O2(g)==CO(g),ΔH1=-110.5Kj/mol C(s)+O2(g)==CO2(g) ,ΔH2=-393.5KJ/mol 则C(s)+CO2(g)==2CO(g)的ΔH为( )A、283.5Kj/mol B、172.5Kj/mol C、-172,5Kj/mol D、-504Kj/mol(╯3╰) 既然饱和烃就是烷烃,而环烷烃不是烷烃,为什么环烷烃是饱和烃? 溶解过程有发生化学反应吗? 高二化学热反应反应物质的量基本计算已知C(s)+O2(g)=CO2(g); △H1 C(s)+1\2O2(g)=CO(g);△H2.求△H1与△H2的相对大小? 含有5个碳原子的烷烃,经催化裂化后生成的烷烃最多有几种 化学反应中,反应物的量和滴加顺序不同对生成物不同的化学反应有哪几种? 试验中不能测出由石墨和氧气反应生成甲烷的反应热ΔH4,但可测出CH4,C,H2 燃烧反应中的反应热ΔH1=-890.3,ΔH2=-393.5,ΔH3=-285.8 根据盖斯定理求ΔH4 环烷烃是饱和烃吗 有能量变化的过程一定发生化学反应吗 高二化学热反应方程式中焓变值变化的问题比如一个热反应方程式.每一项系数X2那么焓变值也有X2但是我们老师说某一年的高考题 有种情况是焓变值不变的,那是怎么一回事啊? 催化裂化反应为什么原料性质变重,反应温度上升 怎样区分别润滑油是不是用加氢裂化基础油调和? 如图,用系统命名法命名下列有机物 催化裂化分馏塔顶压控多少有什么决定 32#基础油中32#是什么意思 CH3 C2H5丨 丨CH3一CH2一CH2一CH2一CH2一CH2一CH2一CH2一CH2一CH2一CH2一CH3这个叫做 6-甲基-7-乙基-12烷 还是叫做 6-乙基-7-甲基-12烷 水溶液中R值是什么意思? 市场上由1类基础油,2类基础油,3类基础油制的的润滑油价格分别是多少?要看具体什么产品?同种产品部同厂家出来的质量和价格都不一样,给个大概的价位给你参考一类:7000-8000二类:8000-10000 请问该有机物如何命名 Excel添加趋势线中的R平方值和截距分别是什么意思? 三类基础油与二类基础油的区分Ultra-S2(60N),Ultra-S3(70N),Ultra-S4(100N),Ultra-S6(150N),Ultra-S8(250N),以上这些有的公司把它们都划分到三类基础油当中,虽然Ultra-S2\S3的粘度指数上写的是二 这个有机物怎么命名, 用R语言估计参数值 请帮忙解释下面这段R语言程序每句的含义,> N x1 x2 n pai for(i in 1:N){+ x1 氢气在加氢裂化过程中起什么作用? 有机物怎么命名,还有怎么判断这些有机物类别. 已知定义在R上的奇函数f(x)满足f(x+2)=-f(x),求f(6)的值 制取粗硅的过程中氢气起什么作用 甲乙两容器中均充入2mol SO2,1mol O2,发生反应2SO2(g)+O2(g)=2SO3(g) △H f(x)是定义在R上的奇函数,对任意∈R,总有f(x+3/2)=-f(x),则(-3/2)的值为多少 浮法玻璃氢气起什么作用 高二化学等效平衡在一固定容积的密闭容器中,保持一定温度,A+2B==3C,已知加入1molA和3molB且达到平衡后,生成了amolC在相同条件下,若在同一容器中,改为加入2molA和8molB,若要求平衡后C在反应混合 对于碳二加氢脱炔过程,为什么把催化剂用于前加氢 氢气的作用 已知2SO2 (g)+O2 (g)⇌2SO3 (g);△H=-197kJ•mol-1.向同温、同体积的三个密闭容器中分别充入气体:(甲) 2mol SO2和1mol O2;(乙) 1mol SO2和0.5mol O2;(丙) 2mol SO3.恒温、恒容下反 对于碳二加氢脱过程,为什么把催化剂不能用于前加氢 反应了什么事件 高二化学等效平衡的讲解要详细的 ~~ 解释透彻的~~拜托啦 什么叫加氢裂化? 在重大政治事件中的表现和认识 怎么写···急 急··· 有关于高二化学 等效平衡的问题一个非等体反应在恒容的情况下,成比例加入与之前相同的药物,那么当反应达到平衡状态时,各物质所占百分数是否与之前一样? “加氢裂化装置”如何翻译成英语 材料反映了什么事件从有最早的历史记录以来,没有一桩伟大的事业能像十八世纪后半期一个主要鞑靼民族跨越亚洲草原向东迁逃那样轰动于世,那样令人激动的了. 各类有机物的性质和可以发生的反应.一些特殊性质等. 什么是催化裂化汽油求答案 关注时事对大学生成才有何意义200字左右 谁可以帮我总结一下高二化学有机物那一块的所有的有机物(甲烷等)的物理性质和化学性质?化学性质最好有方程式 常减压蒸馏汽油、柴油与焦化汽油与柴油的区别 《七律长征》中反映了什么事件?“三军”是指什么?在这一过程中召开过什么重要会议?有何意义?务必一一回答,最好简短一点, 高二化学有机物的一些简单总结(正确的加30分)哪些官能团和NaOH,Na,Cu(OH)2,NaCO3反应?哪些能用溴水检验? 这章我学起来有点吃力,不清楚的就不要回答
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn