有没帅哥给解释一下HOOK,勾子函数是什么东东?我的参考书上都没提到。。 包括开发人员指南... 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 利用键盘钩子实现对Ctrl+C等组合键的屏蔽 刘华志1,朱爱红2 徐梅(1.海军航空工程学院学员旅;2.海军航空工程学院;3.同济大学)摘要:介绍了钩子的概念和运行机制,给出了如何利用键盘钩子实现对Ctrl+C、Ctrl+X和Ctrl+V的拦截和屏蔽。关键词:钩子,拦截,Delphi1.引言 有些软件或网站为了不让别人拷贝信息,都做了处理,譬如:屏蔽了Ctrl+C和鼠标右键复制功能。其实使用键盘钩子和鼠标钩子就可以实现对Ctrl+C和鼠标右键等的屏蔽。本文简单介绍了钩子的概念和运行机制,并详细说明了编程实现方法。2.Win32钩子及其运行机制Win32钩子实际上是一个处理特定消息的程序段,它可以监视系统或进程中的各种事件消息,截获发往目标窗口的消息并进行处理。当触发某个特定的消息时,该消息到达目的应用程序之前,钩子程序就先得到该消息的控制权并捕获该消息。这时钩子程序可以按特定的要求加工处理(改变)该消息,也可以不作任何处理而继续传递该消息,还可以强制结束消息的传递。对每种类型的钩子由系统来维护一个钩子链,最近安装的钩子放在链的开始,而最先安装的钩子放在最后,也就是后加入的钩子先获得控制权。其中,全局钩子函数必须含在DLL中,而线程专用钩子还可以包含在执行文件中。[1]这样,我们就可以在系统中安装自定义的钩子,监视系统中特定事件的发生,完成特定的功能,比如截获键盘、鼠标的输入、屏幕取词和日志监视等等。Win32中钩子类型很多,按事件分主要有键盘钩子、鼠标钩子和日志钩子等,按使用范围有系统钩子和线程钩子。[2]3.实现方法(1)安装钩子函数HHOOK SetWindowsHookEx(int idHook, //钩子的类型HOOKPROC lpfn, //安装的钩子函数的地址HINSTANCE hMod, //此函数所在模块的句柄DWORD dwThreadId //所监控线程的ID);idHook的取值决定Hook要截获消息的类型(如系统消息、键盘消息、鼠标消息或所有消息)和截获方式(如到达目的程序之前还是目的程序处理之后),主要有 :WH_CALLWNDPROC、WH_CALLWNDPROCRET、WH_GETMESSAGE、 WH_JOURNALRECORD、WH_KEYBOARD、WH_MOUSE、WH_SHELL。 idHook的详细使用说明请查看联机帮助。由于本程序要实现键盘钩子功能,所以选用WH_KEYBOARD。Windows发出的消息如符合钩子函数的条件就调用设置的钩子函数(地址为lpfn),钩子函数由用户定义 ,其接口格式必须为 :LRESULT KeyboardHookHandler(iCode: Integer;wParam: WPARAM;lParam: LPARAM);其中参数wParam,lParam因钩子的类型不同有不同含义。参数iCode<0必须设置返回值Result:=CallNextHookEx();SetWindowsHookEx函数多数情况下在DLL中,所以hMod通常为GetModuleHandle(DllfileName:LPCTSTR);dwThreadId如为0,表示监视所有线程。(2)卸载钩子函数安装上钩子函数会降低系统性能,用完后应调用卸载钩子函数UnHookWindowsHookProc以释放系统资源。(3)以下程序在Delphi 6.0中编译通过。步骤如下:①如果Hook在应用程序中实现,若应用程序不是当前窗口时,该Hook就不起作用;如果Hook在DLL中实现,程序在运行中动态调用它,它能实时对系统进行监控。所以采用在DLL中实现Hook。新建一个导出两个函数的DLL文件,在HookUnit.pas中定义了钩子具体实现过程。代码如下:library Hook;uses HookUnit in 'HookUnit.pas';exports EnableHotKeyHook, DisableHotKeyHook;begin hNextHookProc := 0; procSaveExit := ExitProc; ExitProc := @HotKeyHookExit;end.②键盘钩子编程实现过程如下:unit HookUnit;interfaceuses Windows, Messages;var hNextHookProc: HHook;//保存SetWindowsHookEx的返回值 procSaveExit: Pointer; function KeyboardHookHandler(iCode: Integer;wParam: WPARAM;lParam: LPARAM): LRESULT; stdcall; export; function EnableHotKeyHook: BOOL; export;//安装钩子 function DisableHotKeyHook: BOOL; export;//卸载钩子 procedure HotKeyHookExit; far;implementationfunction KeyboardHookHandler(iCode: Integer;wParam: WPARAM;lParam: LPARAM): LRESULT; stdcall; export;const _KeyPressMask=$80000000;//键盘掩码常量begin Result:=0; If iCode < 0 Then //根据SDK说明,若iCode小于0,调用CallNextHookEx并返回 begin Result:=CallNextHookEx(hNextHookProc, iCode, wParam, lParam); Exit; end; // 监测是否按下了Ctrl+X、Ctrl+V、Ctrl+C这三个组合键,若按下则退出,不响应事件 if ((lParam and _KeyPressMask) = 0) and(GetKeyState(vk_control) <0) and ((wParam = Ord('X'))or(wParam = Ord('V'))or(wParam = Ord('C')))then begin Result:=1; Exit; end;end;function EnableHotKeyHook: BOOL; export;begin Result := False;//初始化返回值 if hNextHookProc<>0 then//如果已经注册,直接退出 Exit; //挂上键盘钩子,同时传回值必须保留下来,免得Hook呼叫链结断掉 hNextHookProc:=SetWindowsHookEx(WH_KEYBOARD,KeyboardHookHandler,HInstance,0);//注册hook Result:=hNextHookProc <> 0;//通过返回值确定是否注册成功end;function DisableHotKeyHook: BOOL; export;begin if hNextHookProc<>0 then begin UnhookWindowshookEx(hNextHookProc);//解除Keyboard Hook hNextHookProc:=0;//恢复标志 end; Result:=hNextHookProc=0;//返回是否注销成功 end;procedure HotKeyHookExit;begin if hNextHookProc<>0 then DisableHotKeyHook;//如果忘了解除HOOK,自动代理解除动作 ExitProc:=procSaveExit;end;end.③主程序unit HkUnit;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TForm1 = class(TForm)Memo1: TMemo; procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.DFM}function EnableHotKeyHook: BOOL; external 'HookDll.DLL';//dll中注册hook的函数,传递参数为回调函数的指针function DisableHotKeyHook: BOOL; external 'HookDll.DLL';//dll中注销hook的函数procedure TForm1.Memo1ContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);//屏蔽Memo1鼠标右键弹出的系统菜单begin Handled:=true;end;procedure TForm1.FormCreate(Sender: TObject);begin EnableHotKeyHook;end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);begin DisableHotKeyHook;end;end.4.总结本文介绍了如何拦截Memo的复制、剪切和粘贴功能。调用Memo事件OnContextPopup(或新建空的PopupMenu,然后指向Memo的PopupMenu)可以屏蔽鼠标右键;使用键盘钩子则可以拦截Ctrl+C、Ctrl+X和Ctrl+V,让键盘失效。最大的缺点是:运行该程序后,将无法再使用这三个组合键,如:Word、记事本等都无使用这三个组合键来进行复制、剪切和粘贴功能,也不能用这三个组合键对文件或文件夹进行操作。参考文献:[1].甫尔哈提·阿布都热依木,亚森江·木沙,古丽米拉·克孜别克.关于键盘输入与Win32钩子的探讨.新疆大学学报(自然科学版)[J].2002,19(4).[2].戴春达,符红光.Win32中钩子的实现技术及其应用.计算机应用[J].2002,22(8). 有关DbgridEH 麻烦高手看看,这几句vb调用dll的句子怎样转成delphi的? 注入DLL的问题。 用代码实现VPN服务端。 如何在image的图片中添加一些标记或者文字? 小弟在用fsMDIForm和fsMDIChild时遇到一个小问题? 帮忙看下呀! delphi控制word问题 菜鸟提问(关于函数) 关于tidTcpServer连接客户端个数的问题 Delphi+Oracle,如何使用UpdateSQL往数据库里写数据? 大家看看这个程序,总是提示table是忙的 简单的问题都搞不定,郁闷!
刘华志1,朱爱红2 徐梅
(1.海军航空工程学院学员旅;2.海军航空工程学院;3.同济大学)
摘要:介绍了钩子的概念和运行机制,给出了如何利用键盘钩子实现对Ctrl+C、Ctrl+X和Ctrl+V的拦截和屏蔽。
关键词:钩子,拦截,Delphi1.引言
有些软件或网站为了不让别人拷贝信息,都做了处理,譬如:屏蔽了Ctrl+C和鼠标右键复制功能。其实使用键盘钩子和鼠标钩子就可以实现对Ctrl+C和鼠标右键等的屏蔽。本文简单介绍了钩子的概念和运行机制,并详细说明了编程实现方法。
2.Win32钩子及其运行机制
Win32钩子实际上是一个处理特定消息的程序段,它可以监视系统或进程中的各种事件消息,截获发往目标窗口的消息并进行处理。当触发某个特定的消息时,该消息到达目的应用程序之前,钩子程序就先得到该消息的控制权并捕获该消息。这时钩子程序可以按特定的要求加工处理(改变)该消息,也可以不作任何处理而继续传递该消息,还可以强制结束消息的传递。对每种类型的钩子由系统来维护一个钩子链,最近安装的钩子放在链的开始,而最先安装的钩子放在最后,也就是后加入的钩子先获得控制权。其中,全局钩子函数必须含在DLL中,而线程专用钩子还可以包含在执行文件中。[1]
这样,我们就可以在系统中安装自定义的钩子,监视系统中特定事件的发生,完成特定的功能,比如截获键盘、鼠标的输入、屏幕取词和日志监视等等。Win32中钩子类型很多,按事件分主要有键盘钩子、鼠标钩子和日志钩子等,按使用范围有系统钩子和线程钩子。[2]
3.实现方法
(1)安装钩子函数
HHOOK SetWindowsHookEx(
int idHook, //钩子的类型
HOOKPROC lpfn, //安装的钩子函数的地址
HINSTANCE hMod, //此函数所在模块的句柄
DWORD dwThreadId //所监控线程的ID
);
idHook的取值决定Hook要截获消息的类型(如系统消息、键盘消息、鼠标消息或所有消息)和截获方式(如到达目的程序之前还是目的程序处理之后),主要有 :WH_CALLWNDPROC、WH_CALLWNDPROCRET、WH_GETMESSAGE、 WH_JOURNALRECORD、WH_KEYBOARD、WH_MOUSE、WH_SHELL。
idHook的详细使用说明请查看联机帮助。由于本程序要实现键盘钩子功能,所以选用WH_KEYBOARD。
Windows发出的消息如符合钩子函数的条件就调用设置的钩子函数(地址为lpfn),钩子函数由用户定义 ,其接口格式必须为 :
LRESULT KeyboardHookHandler(iCode: Integer;wParam: WPARAM;lParam: LPARAM);
其中参数wParam,lParam因钩子的类型不同有不同含义。参数iCode<0必须设置返回值Result:=CallNextHookEx();
SetWindowsHookEx函数多数情况下在DLL中,所以hMod通常为GetModuleHandle(DllfileName:LPCTSTR);
dwThreadId如为0,表示监视所有线程。
(2)卸载钩子函数
安装上钩子函数会降低系统性能,用完后应调用卸载钩子函数UnHookWindowsHookProc以释放系统资源。
(3)以下程序在Delphi 6.0中编译通过。步骤如下:
①如果Hook在应用程序中实现,若应用程序不是当前窗口时,该Hook就不起作用;如果Hook在DLL中实现,程序在运行中动态调用它,它能实时对系统进行监控。所以采用在DLL中实现Hook。新建一个导出两个函数的DLL文件,在HookUnit.pas中定义了钩子具体实现过程。代码如下:
library Hook;
uses
HookUnit in 'HookUnit.pas';
exports
EnableHotKeyHook,
DisableHotKeyHook;
begin
hNextHookProc := 0;
procSaveExit := ExitProc;
ExitProc := @HotKeyHookExit;
end.
②键盘钩子编程实现过程如下:
unit HookUnit;
interface
uses
Windows, Messages;
var
hNextHookProc: HHook;//保存SetWindowsHookEx的返回值
procSaveExit: Pointer;
function KeyboardHookHandler(iCode: Integer;wParam: WPARAM;lParam: LPARAM): LRESULT; stdcall; export;
function EnableHotKeyHook: BOOL; export;//安装钩子
function DisableHotKeyHook: BOOL; export;//卸载钩子
procedure HotKeyHookExit; far;
implementation
function KeyboardHookHandler(iCode: Integer;wParam: WPARAM;lParam: LPARAM): LRESULT; stdcall; export;
const
_KeyPressMask=$80000000;//键盘掩码常量
begin
Result:=0;
If iCode < 0 Then //根据SDK说明,若iCode小于0,调用CallNextHookEx并返回
begin
Result:=CallNextHookEx(hNextHookProc, iCode, wParam, lParam);
Exit;
end;
// 监测是否按下了Ctrl+X、Ctrl+V、Ctrl+C这三个组合键,若按下则退出,不响应事件
if ((lParam and _KeyPressMask) = 0) and(GetKeyState(vk_control) <0)
and ((wParam = Ord('X'))or(wParam = Ord('V'))or(wParam = Ord('C')))then
begin
Result:=1;
Exit;
end;
end;
function EnableHotKeyHook: BOOL; export;
begin
Result := False;//初始化返回值
if hNextHookProc<>0 then//如果已经注册,直接退出
Exit;
//挂上键盘钩子,同时传回值必须保留下来,免得Hook呼叫链结断掉
hNextHookProc:=SetWindowsHookEx(WH_KEYBOARD,KeyboardHookHandler,HInstance,0);
//注册hook
Result:=hNextHookProc <> 0;//通过返回值确定是否注册成功
end;
function DisableHotKeyHook: BOOL; export;
begin
if hNextHookProc<>0 then
begin
UnhookWindowshookEx(hNextHookProc);//解除Keyboard Hook
hNextHookProc:=0;//恢复标志
end;
Result:=hNextHookProc=0;//返回是否注销成功
end;
procedure HotKeyHookExit;
begin
if hNextHookProc<>0 then DisableHotKeyHook;//如果忘了解除HOOK,自动代理解除动作
ExitProc:=procSaveExit;
end;
end.
③主程序
unit HkUnit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
implementation
{$R *.DFM}
function EnableHotKeyHook: BOOL; external 'HookDll.DLL';//dll中注册hook的函数,传递参数为回调函数的指针
function DisableHotKeyHook: BOOL; external 'HookDll.DLL';//dll中注销hook的函数
procedure TForm1.Memo1ContextPopup(Sender: TObject; MousePos: TPoint;
var Handled: Boolean);//屏蔽Memo1鼠标右键弹出的系统菜单
begin
Handled:=true;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
EnableHotKeyHook;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
DisableHotKeyHook;
end;
end.
4.总结
本文介绍了如何拦截Memo的复制、剪切和粘贴功能。调用Memo事件OnContextPopup(或新建空的PopupMenu,然后指向Memo的PopupMenu)可以屏蔽鼠标右键;使用键盘钩子则可以拦截Ctrl+C、Ctrl+X和Ctrl+V,让键盘失效。最大的缺点是:运行该程序后,将无法再使用这三个组合键,如:Word、记事本等都无使用这三个组合键来进行复制、剪切和粘贴功能,也不能用这三个组合键对文件或文件夹进行操作。
参考文献:
[1].甫尔哈提·阿布都热依木,亚森江·木沙,古丽米拉·克孜别克.关于键盘输入与Win32钩子的探讨.新疆大学学报(自然科学版)[J].2002,19(4).
[2].戴春达,符红光.Win32中钩子的实现技术及其应用.计算机应用[J].2002,22(8).