28. marts 2004 - 11:13
#1
Ja men så skal du lytte via en callback funktion, som befinder sig i en dll-fil.
Jeg har fundet denne kode til dll'en ude på nettet et eller andet mystisk sted, men den virker!
Den opfanger dog kun Keyboard-taster, for jeg kan ikke helt få de andre paramentre til funktionen SetWindowsHookEx til at virke ordentligt uden den snupper 100% CPU...
library Hook;
uses
Windows,
Messages;
const
CM_SEND_KEY = WM_USER + $1000;
var
Keybrd: HHook;
MemFile: THandle;
Reciever: ^Integer;
{------------------------------------------------------------------------------}
function HookCallBack(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
if (code = HC_ACTION) then
begin
MemFile := OpenFileMapping(FILE_MAP_READ, False, 'KeyReciever');
if (MemFile <> 0) then
begin
Reciever := MapViewOfFile(MemFile, FILE_MAP_READ, 0, 0, 0);
PostMessage(Reciever^, CM_SEND_KEY, wParam, lParam);
UnmapViewOfFile(Reciever);
CloseHandle(MemFile);
end;
end;
Result := CallNextHookEx(Keybrd, Code, wParam, lParam)
end;
{------------------------------------------------------------------------------}
procedure HookOn; stdcall;
begin
Keybrd := SetWindowsHookEx(WH_KEYBOARD, @HookCallBack, HInstance, 0);
end;
{------------------------------------------------------------------------------}
procedure HookOff; stdcall;
begin
UnhookWindowsHookEx(Keybrd);
end;
exports
HookOn,
HookOff;
begin
end.
-------------------------------------------------------------------------------------
Det var dll'en, så mangler der bare din Delphi-unit. Denne her viser tastetrykkene på en TListBox, som bare bliver kaldt List (ved godt jeg kan droppe mange af de uses, det var også bare et gammelt program):
-------------------------------------------------------------------------------------
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Menus, ShellAPI;
const
DLLName = 'Hook.dll';
CM_SEND_KEY = WM_USER + $1000;
type
TKeyHandler = Procedure; stdcall;
type
TMain = class(TForm)
List: TListBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
public
MemFile: THandle;
Reciever: ^Integer;
DLLHandle: THandle;
HookOn,
HookOff: TKeyHandler;
procedure ScanHook(var Message: TMessage); message CM_SEND_KEY;
end;
var
Main: TMain;
implementation
{$R *.dfm}
procedure TMain.ScanHook(var Message: TMessage);
var
KeyName: array[0..100] of Char;
begin
GetKeyNameText(Message.LParam, @KeyName, 100);
if Message.LParam shr 30 = 1 then
List.Items.Add(KeyName);
SendMessage(List.Handle, WM_VSCROLL, SB_PAGEDOWN, 0);
end;
procedure TMain.FormCreate(Sender: TObject);
begin
DLLHandle :=
LoadLibrary( PChar(ExtractFilePath(Application.Exename) + DLLName ) );
@HookOn := GetProcAddress(DLLHandle, 'HookOn');
@HookOff := GetProcAddress(DLLHandle, 'HookOff');
MemFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(Integer), 'KeyReciever');
Reciever := MapViewOfFile(MemFile, FILE_MAP_WRITE, 0, 0, 0);
Reciever^ := Handle;
HookOn;
end;
procedure TMain.FormDestroy(Sender: TObject);
begin
if Assigned(HookOff) then
HookOff;
if (DLLHandle <> 0) then
FreeLibrary(DLLHandle);
if (MemFile <> 0) then
UnmapViewOfFile(Reciever);
CloseHandle(MemFile);
end;
end.