Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi keyboard hook / mmf (https://www.delphipraxis.net/131485-keyboard-hook-mmf.html)

cherry 25. Mär 2009 16:00


keyboard hook / mmf
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo erstmal...

Gewünschtes Ergebnis:
einen tastenhook setzen (eigene dll)
auf tastenereignisse reagieren
zwischen hook dll und Programm via mmf kommunizieren

Aktueller Stand:
Habe eine kleine Testanwendung erstellt die bereits alles beinhaltet was ich will.
gestützt auf diesem Tutorial.

Probleme:
Ich habe verschiedene Probleme mit der Anwendung:
manchmal funktioniert die Anwendung einwandfrei: Tastenhooks werden Abgefangen Broadcast der
eigenen Message wird gesendet und von meinem Programm richtig interpretiert, sprich ProcessID und
lParam usw. werden auf die Labels ausgegeben.

Nun manchmal passiert nix, sprich die Anwendung startet, reagiert aber nicht auf Tastatureingaben.

Wahrscheinlich liegt das Grösste Problem meiner Anwenung beim Handling von MMF. Respektive beim
Öffnen und schliessen der MFF oder beim Freigeben der zugehörigen Pointer...

Worstcase: Mein Programm hängt sich auf, Messages werden nicht richtig weitergeleitet =
Explorer andere Programme stürtzen ab...

Wenn ich eine Fehlermeldung erhalte, dann ist es eine Speicherverletzung...

Bitte:
Kannst du bitte einen Blick über meinen Code werfen und dir das Handling der MMFs mal genäuer
anschauen..?! -Ich habe keine Ahnung was ich falsch mache...

Vielen Dank

cherry 26. Mär 2009 08:18

Re: keyboard hook / mmf
 
Damit ihr nicht den ganzen karumpel herunterladen müsst, hier doch noch einen Ausschnitt aus meinem Quelltext (So wie er momentan kompilliert ist.)...

Anzufügen ist: Vorhin hat das Programm funktioniert, bis ich ein anderes Fenster (ein Fenster nicht von meinem Programm) aktiviert habe. Wenn ein anderes Programm fokusiert ist, gibts bei jeder Taste die ich drücke eine "Zugriffsverletzung" bei irgend einer Speicheradresse...

an was liegts denn wohl?

hooks dll:

Delphi-Quellcode:
library hooks;

uses
  Windows,
  Messages,
  Dialogs;

var
  HookHandle: Cardinal = 0;
  WindowHandle: Cardinal = 0;

const
  keybmsg = 'KeyboardHookMessage_Enemyleft';

{$INCLUDE Include\HookingDLL_Data.pas}

function GetPView: Pointer; stdcall;
begin
  Result := lpView;
end;

function CreateMMF: Boolean;
begin
  Result := False;
  MapHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(TDLLData), MMFName);
  if MapHandle <> 0 then
  begin
    if Assigned(lpView) then
      Result := True
    else
      CloseHandle(MapHandle);
  end;
end;

function OpenAndMapMMF: Pointer;
begin
  Result := nil;
  MapHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(TDLLData), MMFName);
  if MapHandle <> 0 then
  try
    lpView := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TDLLData))
  finally
    CloseHandle(MapHandle);
  end;
  Result := lpView;
end;

function CloseAndUnmapMMF(view: Pointer): Boolean;
begin
  result := UnMapViewOfFile(view);
end;

function KeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
  lpView: PDLLData;
begin
  // it's possible to call CallNextHookEx conditional only.
  Result := CallNextHookEx(HookHandle, nCode, wParam, lParam);
  case nCode < 0 of
    TRUE: exit;// if code smaller 0 nothing has to be done
    FALSE:
    begin
      lpView := OpenAndMapMMF;
      if Assigned(lpView) then
      try
        lpView^.nCode := nCode;
        lpView^.ProcessID := GetCurrentProcessID;
        lpView^.ThreadID := GetCurrentThreadID;
        lpView^.TestStr := '#enemyleft';
        // we use HWND_BROADCAST to send the message to any window which handles this WM
        SendMessage(HWND_BROADCAST, lpView^.WM_KEYBHOOKMSG, wParam, lParam);
      finally
        CloseAndUnMapMMF(lpView);
      end;
    end;
  end;
end;

function InstallHook(Hwnd: Cardinal): Boolean; stdcall;
begin
  //lpView^.WM_KEYBHOOKMSG := WM_USER+1;
 // WM_KEYBHOOKMSG := RegisterWindowMessage(WM_USER+13);
  Result := False;
  if HookHandle = 0 then
  begin
    // install the hook
    HookHandle := SetWindowsHookEx(WH_KEYBOARD, @KeyboardHookProc, HInstance, 0);
    // save the given window handle
    WindowHandle := Hwnd;
    Result := TRUE;
  end;
end;

procedure FreeMMF;
begin
  //UnmapviewofFile(lpView);
  //CloseHandle(MapHandle);
end;

function UninstallHook: Boolean; stdcall;
begin
  //
  FreeMMF;
  // uninstall hook from hook chain
  Result := UnhookWindowsHookEx(HookHandle);
  HookHandle := 0;
end;

procedure DLLMain;
begin
  if CreateMMF then
  begin
    // register our private window messages
    lpView^.WM_KEYBHOOKMSG := RegisterWindowMessage(keybmsg);
  end;
  //FreeMMF;
end;

exports
  // export the installation and deinstallation routine
  InstallHook,
  UninstallHook,
  GetPView;

begin


end.
Programm:

Delphi-Quellcode:

...

procedure TForm1.DefaultHandler(var Message); //override
var
  MsgRecord: TDLLData;
begin
  with TMessage(Message) do
  begin
    if (Msg = WM_KEYBHOOKMSG) then
    begin
      MsgRecord.Msg := Msg;
      MsgRecord.Handle := wParam;
      MsgRecord.wnd := wParam;
      MsgRecord.Info := lParam;
      //if MsgRecord.wnd <> Handle then
        KeybdMessage(MsgRecord);
    end
    else
      inherited DefaultHandler(message);
  end;
end;


procedure TForm1.KeybdMessage(var MsgRecord: TDLLData);
var
  bla: PDLLData;
begin
  if MsgRecord.wnd = VK_SNAPSHOT then
  begin
    Caption := Format('SNAPSHOT :%d', [MsgRecord.wnd]);
    PrintScreen;
  end
  else
    Caption := Format(':%d', [MsgRecord.wnd]);
  // get pointer to MMF
  try
    bla := GetPView;//OpenAndMapMMF;
    //if Assigned(bla) then
    //begin
      Label1.Caption := Format('%d', [bla^.ProcessID]);
      Label2.Caption := Format('%d', [bla^.ThreadID]);
      Label5.Caption := bla^.TestStr;
    //end;
  finally
    //CloseAndUnmapMMF(bla);
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  UninstallHook;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  OpenAndMapMMF;
  extpath := ExtractFilePath(ParamStr(0));//+'\hooks.dll';
  putbinresto('HookDLL', extpath);
  loadDll;
  InstallHook(Application.Handle);
end;

...

cherry 27. Mär 2009 07:02

Re: keyboard hook / mmf
 
Is wohl ein bisschen zu mühsam oder zu uninteressant, wie?! :cry:
Na jedenfalls habe ich folgendes festgestellt:

Das Programm funktioniert eigentlich so wie es soll... die Fehler passieren eigentlich erst wenn
ich den Fokus nicht mehr auf meinem Programm habe und eine Tasteneingabe mache. Denn dann passiert die gennante Speicherverletzung...

Irgendetwas scheint anders zu sein wenn der Fokus nicht mehr auf meinem Programm ist, aber ich bin wohl zu dumm um zu sehen was das ist.

Vielen Dank für deine Tipps... :cat:


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:03 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz