各位DX,TX,我想做一个健康键盘输入的程序,想只用钩子。我在创建窗口时候装了一个钩子,代码如下:
KBHook:=SetWindowsHookEx(WH_KEYBOARD,
{callback —>} @KeyboardHookProc,
HInstance,
0) ;回调函数我是这样写的:
function KeyboardHookProc(Code: Integer; WordParam: Word; LongParam: LongInt) : LongInt;
var
i:Integer;
begin
if(GetKeyState(WordParam) and $8000) = $8000 then
begin
case WordParam of
vk_Space: Form1.Label1.Caption:=Form1.Label1.Caption+IntToStr(0);
vk_Right: Form1.Label1.Left:=Form1.Label1.Left + 5;
vk_Left: Form1.Label1.Left:=Form1.Label1.Left - 5;
vk_Up: Form1.Label1.Top:=form1.Label1.Top - 5;
vk_Down: Form1.Label1.Top:=form1.Label1.Top + 5;
end; {case}
end; 目前的情况是只要焦点在本程序,label1就可以随着键盘的输入移动。但只要焦点切换到其他程序,再按方向键,就会把当前焦点的程序或者窗口结束掉。我把SetWindowsHookEx的HInstance改为0后,不会影响到其他程序,但也捕获不到键盘输入了。
还有,我注入钩子时候,杀毒软件会报。
KBHook:=SetWindowsHookEx(WH_KEYBOARD,
{callback —>} @KeyboardHookProc,
HInstance,
0) ;回调函数我是这样写的:
function KeyboardHookProc(Code: Integer; WordParam: Word; LongParam: LongInt) : LongInt;
var
i:Integer;
begin
if(GetKeyState(WordParam) and $8000) = $8000 then
begin
case WordParam of
vk_Space: Form1.Label1.Caption:=Form1.Label1.Caption+IntToStr(0);
vk_Right: Form1.Label1.Left:=Form1.Label1.Left + 5;
vk_Left: Form1.Label1.Left:=Form1.Label1.Left - 5;
vk_Up: Form1.Label1.Top:=form1.Label1.Top - 5;
vk_Down: Form1.Label1.Top:=form1.Label1.Top + 5;
end; {case}
end; 目前的情况是只要焦点在本程序,label1就可以随着键盘的输入移动。但只要焦点切换到其他程序,再按方向键,就会把当前焦点的程序或者窗口结束掉。我把SetWindowsHookEx的HInstance改为0后,不会影响到其他程序,但也捕获不到键盘输入了。
还有,我注入钩子时候,杀毒软件会报。
解决方案 »
- 一个简单问题
- 关于SendMessage获取ListBox内容的问题
- [群群]半年没有散分了,散散分
- 如何把与datetimepicker中日期里相同月份的数据检索出来
- 编写木马程序怎么认定犯罪,刑罚怎么计算?
- delphi 7中用什么做报表比较简单,可以用Crystal Report吗?
- 如何将应用程序改成dll?
- 在2000下用delphi5编辑的窗体和控件,在98下执行时大小完全不同,反过来也是。这是为什么?
- 同志们,帮助一下乡下人吧 !转换鼠标左右键 !
- 如何在CSDN上发布自己的软件
- D7 不能这样使用 Tmeminifile.Create('') ???
- 在cxGrid中导出的xls文件,打开特别慢,为什么?
KBHook:=SetWindowsHookEx(WH_KEYBOARD,
{callback —>} @KeyboardHookProc,
0,
GetCurrentThreadId);这样其他窗口就不会关闭了。
此外你没有再钩子会掉函数中加入:
Result := CallNextHookEx(KBHook, Code, WordParam, LongParam);
改一下你的代码:
if code < 0 then
begin
Result := CallNextHookEx(KBHook, Code, WordParam, LongParam);
Exit;
end;
if(GetKeyState(WordParam) and $8000) = $8000 then
begin
case WordParam of
vk_Space: Form1.Label1.Caption:=Form1.Label1.Caption+IntToStr(0);
vk_Right: Form1.Label1.Left:=Form1.Label1.Left + 5;
vk_Left: Form1.Label1.Left:=Form1.Label1.Left - 5;
vk_Up: Form1.Label1.Top:=form1.Label1.Top - 5;
vk_Down: Form1.Label1.Top:=form1.Label1.Top + 5;
end; {case}
end;
Result := CallNextHookEx(KBHook, Code, WordParam, LongParam);但是当这个窗体失去焦点后,钩子就不起作用了,如果你想这个窗体失去焦点的时候也是生效,要使用全局钩子,必须把这个钩子放到dll中。
还有我实际上是想监控F12是否按下,是否还有其他不会被杀毒软件查杀的办法?用消息,directx怎样?
在你的form类里面添加一个消息处理函数:
procedure hotkey(var msg:tmessage);message wm_hotkey;实现:
procedure TForm1.hotkey(var msg:tmessage);
begin
if msg.LParamHi = VK_F12 then
begin
//你的处理代码
end;
end;
声明一个全局变量:
atom: TAtom;(要把windows.pas use进来)
然后在你的create函数里面加上:
atom := GlobalAddAtom('My_HOT_KEY');
RegisterHotKey(Handle, atom, MOD_CONTROL, VK_F12);//(MOD_CONTROL的意思就是按下ctrl键)
最后再你的close事件里面加上
GlobalDeleteAtom(atom);就ok了,呵呵呵
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;
ReadPos : Integer;
end;
PShared=^TShared;
implementationend.
//下面是动态库源码,你可以根据你自己的情况修改
library HookDll;{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }uses
SysUtils,
Classes,
Windows,
Generics.Collections,
HookType in 'HookType.pas';{$R *.res}const
KeyPressMask = $80000000;
var
MemFile,HookMutex : THandle;
hOldKeyHook : Cardinal;
ProcSaveExit : Pointer;
Shared : PShared;
FormHandle: THandle;//键盘钩子过滤函数
function KeyHookProc(iCode: Integer; wParam: WPARAM ; lParam: LPARAM):LRESULT ; stdcall; export;
begin
if iCode < 0 then
Result := CallNextHookEx(hOldKeyHook, iCode, wParam, lParam)
else
begin
if (lparam and $80000000) = 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 ; stdcall; export;
begin
Shared^.KeyCount := 0;
Shared^.ReadPos := 0;
if hOldKeyHook=0 then
begin
hOldKeyHook := SetWindowsHookEx(WH_KEYBOARD,
KeyHookProc,
HInstance,
0);
end;
Result := (hOldKeyHook <> 0);
end;//撤消钩子过滤函数
function DisableKeyHook: BOOL ; stdcall; export;
begin
if hOldKeyHook<> 0 then
begin
UnHookWindowsHookEx(hOldKeyHook); // 解除 Keyboard Hook
hOldKeyHook:= 0;
Shared^.KeyCount := 0;
Shared^.ReadPos := 0;
end;
Result := (hOldKeyHook = 0);
end;//取得键盘缓冲区中击键的个数
function GetKeyCount :Integer ; stdcall; export;
begin
Result:= Shared^.KeyCount;
end;//取得键盘缓冲区的键
function GetKey() : char ; stdcall; export;
begin
if ((Shared^.KeyCount > 0) and (Shared^.ReadPos < Shared^.KeyCount)) or
(Shared^.ReadPos > Shared^.KeyCount) then
begin
Result:=shared^.Keys[Shared^.ReadPos];
Inc(Shared^.ReadPos);
if Shared^.ReadPos >= BUFFER_SIZE then
Shared^.ReadPos := 0;
end
else
begin
Result := #0;
end;end;//清空键盘缓冲区
procedure ClearKeyString ; stdcall; export;
begin
shared^.KeyCount := 0;
Shared^.ReadPos := 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.
使用方法:
先EnableKeyHook();
然后:
你做一个定时器,时间设成10毫秒或者50毫秒的,短点儿,在定时器事件中
用c := GetKey();取得Char,然后做你要做的事情就行了。退出的时候用DisableKeyHook;
结贴了。