重金求助!!!!!!!1(200分)

  • 主题发起人 主题发起人 yishengdxx
  • 开始时间 开始时间
Y

yishengdxx

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大虾,小弟重金求助以 键盘事件的钩子函数的源程序
要求如下,窗体在后台活动,能侦测windows的一切键盘触发
小弟者下可是倾家荡产了:-) 没分可用了,各位大哥行行好,
别嫌分少了,200分 [:(]
 
DFS控件包里面有一个dll,应该可以的,代码如下。
{.$DEFINE DFS_DEBUG}

{ The DFSKbMon.DLL library. }

{ Intended for use with the TDFSStatusBar component (DFSStatusBar.pas), and
intended to be accessed by the DFSKb unit. }

{ This DLL provides a notification mechanism for system wide monitoring of the
Caps, Num &
Scroll lock keys. Interested parties are notified via a custom
windows message as returned by the RegisterKeyboardHook function. }

library DFSKbMon;

uses
{$IFDEF DFS_DEBUG}
Debug, SysUtils,
{$ENDIF}
Windows;

const
MAX_CLIENTS = 256;

type
PHookData = ^THookData;
THookData = record
KeyboardHookHandle: HHOOK;
UsageCount: integer;
ClientIndex: integer;
Clients: array[0..MAX_CLIENTS-1] of HWND;
end;


var
MapFile: THandle;
WM_INDICATORKEY: UINT;
HookData: PHookData;


procedure MapFileMemory;
var
ZeroMem: boolean;
begin

MapFile := CreateFileMapping($FFFFFFFF, NIL, PAGE_READWRITE, 0,
SizeOf(THookData), 'DFSKbMon Client List');
if (MapFile = 0) then

begin

MessageBox(0, 'DFSKbMon DLL', 'Could not create file map object', MB_OK);
end else
begin

ZeroMem := GetLastError <> ERROR_ALREADY_EXISTS;
HookData := MapViewOfFile(MapFile, FILE_MAP_ALL_ACCESS, 0, 0,
SizeOf(THookData));
if (HookData = NIL) then

begin

CloseHandle(MapFile);
MessageBox(0, 'DFSKbMon DLL', 'Could not map file', MB_OK);
end else

if ZeroMem then

FillChar(HookData^, SizeOf(THookData), #0);
end;

end;


procedure UnmapFileMemory;
begin

if (HookData <> NIL) then

begin

UnMapViewOfFile(HookData);
HookData := NIL;
end;

if (MapFile <> 0) then

begin

CloseHandle(MapFile);
MapFile := 0;
end;

end;


procedure AddClient(Wnd: HWND);
begin

if (HookData <> NIL) then

begin

{$IFDEF DFS_DEBUG}
Debug.Log(TRUE, 'DFSKbMon: Added ' + IntToHex(Wnd, 8) + ' at index ' +
IntToStr(HookData^.ClientIndex));
{$ENDIF}
HookData^.Clients[HookData^.ClientIndex] := Wnd;
inc(HookData^.ClientIndex);
end;

end;


procedure RemoveClient(Wnd: HWND);
var
x: integer;
begin

if (HookData <> NIL) then

begin

{$IFDEF DFS_DEBUG}
Debug.Log(TRUE, 'DFSKbMon: Trying to remove ' + IntToHex(Wnd, 8));
{$ENDIF}
for x := 0 to HookData^.ClientIndex-1do

begin

if HookData^.Clients[x] = Wnd then

begin

{$IFDEF DFS_DEBUG}
Debug.Log(TRUE, ' Found at index ' + IntToStr(HookData^.ClientIndex));
{$ENDIF}
if x < HookData^.ClientIndex-1 then

Move(HookData^.Clients[x+1], HookData^.Clients[x],
(HookData^.ClientIndex - x - 1) * SizeOf(HWND));
dec(HookData^.ClientIndex);
break;
end;

end;

end;

end;




// Keyboard hook callback
function KeyboardHookCallBack(Code: integer;
KeyCode: WPARAM;
KeyInfo: LPARAM): LRESULT;
stdcall;
var
x: integer;
State: ShortInt;
begin

if (Code >= 0) and (HookData <> NIL) then

begin

// Is it one of the indicator keys, and is it not a repeat
if ((KeyCode = VK_CAPITAL) or (KeyCode = VK_NUMLOCK) or
(KeyCode = VK_SCROLL)) and
// This checks to see if the key is being pressed (bit 31) and if it was
// up before (bit 30). Wedo
n't care about key releases or keys that
// were alreadydo
wn. That just makes us flicker...
(((KeyInfo SHR 31) and 1) = 0) {and (((KeyInfo SHR 30) and 1) = 0)} then

begin

State := GetKeyState(KeyCode);
for x := 0 to HookData^.ClientIndex-1do

PostMessage(HookData^.Clients[x], WM_INDICATORKEY, KeyCode, State);
end;

end;


Result := CallNextHookEx(HookData^.KeyboardHookHandle, Code, KeyCode, KeyInfo);
end;


// Utility routins for installing the windows hook for keypresses
function RegisterKeyboardHook(Handle: HWND): UINT;
stdcall;
{ This is really silly, but that's the way it goes. The only way to get the }
{ module handle, *not* instance, is from the filename. The Microsoft example}
{ just hard-codes the DLL filename. I think this is a little bit better. }
function GetModuleHandleFromInstance: THandle;
var
s: array[0..512] of char;
begin

{ Find the DLL filename from the instance value. }
GetModuleFileName(hInstance, s, sizeof(s)-1);
{ Find the handle from the filename. }
Result := GetModuleHandle(s);
end;

begin

if (HookData <> NIL) then

begin

if HookData^.KeyboardHookHandle = 0 then

{ See the Microsoft KnowledgeBase, PSS ID Number: Q92659, for a }
{ discussion of the Windows bug that requires GetModuleHandle to be used.}
HookData^.KeyboardHookHandle := SetWindowsHookEx(WH_KEYBOARD,
KeyboardHookCallBack, GetModuleHandleFromInstance, 0);

inc(HookData^.UsageCount);
AddClient(Handle);

Result := WM_INDICATORKEY;
end else

Result := 0;
end;


procedure DeregisterKeyboardHook(Handle: HWND);
stdcall;
begin

if (HookData <> NIL) then

begin

dec(HookData^.UsageCount);
RemoveClient(Handle);
if HookData^.UsageCount < 1 then

begin

UnhookWindowsHookEx(HookData^.KeyboardHookHandle);
HookData^.KeyboardHookHandle := 0;
end;

end;

end;


procedure LibraryProc(Reason: Integer);
begin

case Reason of
DLL_PROCESS_ATTACH:
begin

{$IFDEF DFS_DEBUG}
Debug.Log(TRUE, 'DFSKbMon: loaded.');
{$ENDIF}
MapFile := 0;
HookData := NIL;
MapFileMemory;
end;

DLL_PROCESS_DETACH:
begin

UnmapFileMemory;
{$IFDEF DFS_DEBUG}
Debug.Log(TRUE, 'DFSKbMon: unloaded.');
{$ENDIF}
end;

end;

end;


exports
RegisterKeyboardHook,
DeregisterKeyboardHook;


begin

WM_INDICATORKEY := RegisterWindowMessage('DFSKbMon.WM_INDICATORKEY');
DLLProc := @LibraryProc;
LibraryProc(DLL_PROCESS_ATTACH);
end.

 
这个有好多的,其实求是没有窗体,不在屏幕上显示,在ctrl+alt+delete中不显示(会在进程列表中显示)
这种东西一般是用在干坏事的时候哦
 
刚才说的各个模块都可在大富翁中找到。
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部