接着线程级那些代码来做,上程序只有在本程序内按字母A才会发声,只为是线程级的,现在做的是系统级,只要按上钩子,无论在哪按A都会发声
分两步:
一、建立 DLL, 并在 DLL 实现钩子的设置、释放和钩子函数;
二、再建一个工程调用测试.
先写个dll
library key_a;
uses
SysUtils,
Windows,
messages,
Classes;
{$R *.res}
var
hok:hhook;
function keyb(ncode:integer;wparam:wparam;lparam:lparam):lresult;stdcall;
begin
if wparam=65 then
messagebeep(0);//按A发声
result:=callnexthookex(hok,ncode,wparam,lparam);
end;
procedure sethok;stdcall;
begin
hok:=setwindowshookex(wh_keyboard,@keyb,hinstance,0);
end;
procedure unhok;stdcall;
begin
unhookwindowshookex(hok);
end;
exports
sethok,unhok;
begin
end.
按Ctrl+F9 编译,生成key_a.dll
调用key_a.dll文件
新建窗体,加两个button,一个用来安装,另个用来卸载
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure sethok;stdcall;external 'key_a.dll';
procedure unhok;stdcall;external 'key_a.dll';
procedure TForm1.Button1Click(Sender: TObject);
begin
sethok;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
unhok;
end;
end.
上面调用是静态调用,下面说动态调用
主是要用API来动态调用
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{要先要定义和 DLL 中同样参数和返回值的的过程类型 ,
万一前辈用的函数类型}
type
tfun=procedure;stdcall;
var
had:thandle;
sethok,unhok:tfun;
procedure TForm1.Button1Click(Sender: TObject);
begin
had:=loadlibrary('key_a.dll');
sethok:=getprocaddress(had,'sethok');
unhok:=getprocaddress(had,'unhok');
sethok;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
unhok;
FreeLibrary(had);
end;
end.
函数说明:
LoadLibrary(dll名字)载入dll并返回一个句柄
getprocaddress(上面的句柄,dll里面的函数)得到dll里面函数的入口地址
posted on 2008-11-12 18:54
小叶子 阅读(583)
评论(0) 编辑 收藏 引用 所属分类:
delphi使用钩子函数