AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Hook in Klasse einbinden...

Ein Thema von glkgereon · begonnen am 28. Aug 2005 · letzter Beitrag vom 29. Aug 2005
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#1

Hook in Klasse einbinden...

  Alt 28. Aug 2005, 12:11
Hi

ich habe folgendes Konstrukt(gekürzt):
Delphi-Quellcode:
TTastaturStatistik = class(TObject)
  //Tastatur
  private
    FOverAll: Int64;
    HookHandle: Cardinal;
    //Set-Methoden
    procedure SetKeyHits(New: Int64);
    //Hook
    procedure Hook;
    procedure UnHook;
  public
    constructor Create;
    destructor Destroy;
    //Propertys
    property KeyHits:Int64 read FOverAll write SetKeyHits;
  end;

implementation

procedure TTastaturStatistik.Hook;
//Hook aktivieren
begin
  HookHandle := SetWindowsHookEx(WH_KEYBOARD_LL, LLKeyboardHookProc, hInstance, 0); //HIER 2
  if HookHandle = 0 then RaiseLastOSError;
end;

procedure TTastaturStatistik.UnHook;
//Hook deaktivieren
begin
  if HookHandle <> 0 then
    begin
    UnhookWindowsHookEx(HookHandle);
    HookHandle := 0;
    end;
end;

function LLKeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
//Wenn Taste gedrückt wird
begin
  if nCode = HC_ACTION then //lParam ist richtiger Typ
    Inc(FOverAll); //HIER 1
  Result := CallNextHookEx(HookHandle, nCode, wParam, lParam);
end;
nur das geht ja nicht (HIER 1), da ich so FOverAll ja nicht ansprechen kann

wenn ich allerdings LLKeyboardHookProc als Private der Klasse deklariere, dann kommt bei HIER 2 der Fehler das LLKeyboardHookProc eine reguläre Procedure und kein Methodenzeiger sei...

hat irgendwer eine Lösung für mich?

Edit: DUDEN, hilf mir
der Code ist übrigens im wesentlichen von Flocke...
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Hook in Klasse einbinden...

  Alt 28. Aug 2005, 15:48
Ich weiss nicht mehr genau wie es ging, aber es gibt da einen kleinen asm trick, um eine klassenmethode beim hook zu registrieren.

und es müsste auch mit

SetWindowsHookEx(WH_KEYBOARD_LL, TTastaturStatistik.LLKeyboardHookProc, hInstance, 0); //HIER 2 also mit dem klassennamen(!) funktionieren.

noch fragen?

du musst mal im forum suchen, irgendwo steht der assembler trick auch. müsste sogar in dem thread von flocke sein.
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Hook in Klasse einbinden...

  Alt 28. Aug 2005, 16:16
mit dem klassennamen das geht nicht weil der unsichtbare Self-Parameter nicht bei der HookProcedure als erster Parameter mitkommt, sondern es kommt die Action mit. Als Umweg könnte man zur Laufzeit eine Procedure im Speicher erzeugen und dort fest den Self-Paremter reinpatchen. Diese zur Laufzeit erzeugte Procedure kann dann wiederum die Klassenmethode mit den entsprechenden parametern aufrufen.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

Re: Hook in Klasse einbinden...

  Alt 28. Aug 2005, 16:29
Du kannst es ähnlich machen wie Delphi mit den Fensterprozeduren. Dazu solltest du dir mal den Code zu "MakeObjectInstance" in Classes.pas ansehen.

Du brauchst in Assembler einen Stub wie:
Code:
pop eax  // Rücksprungadresse runter
push Self // Self auf den Stack legen (32-Bit Wert / Zeiger)
push eax  // Rücksprungadresse wieder drauf
jmp TTastaturStatistik.LLKeyboardHookProc
LLKeyboardHookProc muss natürlich "stdcall" deklariert sein.

Den Speicherblock musst du dir mit
Block := VirtualAlloc(nil, PageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); holen und dann statt deiner Prozedur eben "Block" als Zeiger bei SetWindowsHookEx angeben.

[Nachtrag]

Beispielcode (ungetestet):

Delphi-Quellcode:
function ClassProcAsHook(Obj: TObject; Method: Pointer): Pointer;
type
  PCodeBlock = ^TCodeBlock;
  TCodeBlock = packed record
    bPopEax: byte;
    bPushImm32: byte;
    lSelf: longint;
    bPushEax: byte;
    bJmpDisp32: byte;
    lDisp: longint;
  end;
var
  Block: PCodeBlock;
begin
  Block := VirtualAlloc(nil, SizeOf(TCodeBlock), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  Block^.bPopEax := $58;
  Block^.bPushImm32 := $68;
  Block^.lSelf := longint(Obj);
  Block^.bPushEax := $50;
  Block^.bJmpDisp32 := $E9;
  Block^.lDisp := longint(Method) - (longint(@Block^.lDisp) + 4);
  Result := Block;
end;
Beim Opcode für PUSH bin ich mir nicht ganz sicher, bitte überprüfen.
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat
NicoDE
(Gast)

n/a Beiträge
 
#5

Re: Hook in Klasse einbinden...

  Alt 28. Aug 2005, 16:37
http://www.delphipraxis.net/internal...=387393#387393
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#6

Re: Hook in Klasse einbinden...

  Alt 28. Aug 2005, 16:44
@Nico: natürlich wesentlich besser, da nicht eben so hingehackt 8)
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#7

Re: Hook in Klasse einbinden...

  Alt 28. Aug 2005, 19:15
hmmm

ich glaub das is mir etwas zu schnell...

also ich soll zur laufzeit eine procedure erzeugen, die dann die klassen-proc aufruft?

auch wenn ihr das eigentlich nicht macht, könntet ihr mir das ausnahmsweise in meinen quelltext einbauen? *ganz lieb guck*

ich werds zwar auch versuchen, aber ehrlich gesagt würde ich da keine große hoffnung hegen
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
NicoDE
(Gast)

n/a Beiträge
 
#8

Re: Hook in Klasse einbinden...

  Alt 28. Aug 2005, 19:31
Also...

Das Problem ist, dass die Win32-API-Funktion eine Callback-Funktion mit einem bestimmten Funktionstyp erwartet. Methoden haben aber einen impliziten ersten Parameter (Self). Es nutzt also nichts, die Methode an die API-Funktion weiterzugeben, da sie immer inkompatibel ist.
Die Lösung besteht nun darin, eine Funktion zur Laufzeit zu erzeugen (da Self nicht statisch ist), welche aufrufkompatibel zur API-Funktion ist und nichts anderes macht, als deine gewünschte Methode in der Klasse aufzurufen. Es gibt dann also zwei Callback-Funktionen: eine Callback-Methode und eine Callback-Funktion (die wiederum nur die Methode aufruft).

Am besten siehst Du dir das Beispiel im o.g. Thead an.
( http://www.delphipraxis.net/internal...=387139#387139 )
  Mit Zitat antworten Zitat
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#9

Re: Hook in Klasse einbinden...

  Alt 28. Aug 2005, 19:55
also müsste ich das in etwa so machen:

Delphi-Quellcode:
type
  TCallback = procedure(bla: Integer); cdecl;
  TMethodCallback = procedure(bla: Integer) of object; cdecl;
TDings = class
private
  FCallback: TCallback;
  FMethodCallback: TMethodCallback;
  Method(bla: Integer); cdecl;
end;

//erstellen
  FCallback := TCallback(MakeCdeclCallback(TMethod(FMethodCallback), 4));
  FMethodCallback := Method;


procedure TDings.Method(bla: Integer); cdecl;
begin
  ShowMessage('MethodCallback: ' + string(Text));
end;

//weg damit
  FreeCdeclCallback(@FCallback);

//Hooken
HookHandle := SetWindowsHookEx(WH_KEYBOARD_LL, FCallback, hInstance, 0);
stimmt das alles?
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#10

Re: Hook in Klasse einbinden...

  Alt 28. Aug 2005, 21:37
Eher so (auf dein erstes Beispiel angewendet, ungetestet):
Code:
TTastaturStatistik = class(TObject)
  //Tastatur
  private
    FOverAll: Int64;
    HookHandle: Cardinal;
    [b]FCallback: Pointer;[/b]
    //Set-Methoden
    procedure SetKeyHits(New: Int64);
    //Hook
    procedure Hook;
    procedure UnHook;
    [b]function LLKeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;[/b]
  public
    constructor Create;
    destructor Destroy;
    //Propertys
    property KeyHits:Int64 read FOverAll write SetKeyHits;
  end;

implementation

procedure TTastaturStatistik.Hook;
//Hook aktivieren
begin
  [b]FCallback := MakeStdcallCallback([color=red]LLKeyboardHookProc[/color]);[/b]
  HookHandle := SetWindowsHookEx(WH_KEYBOARD_LL, [b]FCallback[/b], hInstance, 0); //HIER 2
  if HookHandle = 0 then RaiseLastOSError;
end;

procedure TTastaturStatistik.UnHook;
//Hook deaktivieren
begin
  if HookHandle <> 0 then
    begin
    UnhookWindowsHookEx(HookHandle);
    HookHandle := 0;
    end;
[b] if FCallback <> nil then
  begin
    FreeCallback(FCallback);
    FCallback := nil;
  end;[/b]
end;

function [b]TTastaturStatistik[/b].LLKeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
//Wenn Taste gedrückt wird
begin
  if nCode = HC_ACTION then //lParam ist richtiger Typ
    Inc(FOverAll); //HIER 1
  Result := CallNextHookEx(HookHandle, nCode, wParam, lParam);
end;
So ist LLKeyboardHookProc eine Methode deiner Klasse und du kannst Self usw. darin benutzen.

Bei der roten Stelle bin ich mir nicht sicher, ob da ein Cast herum muss.
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:59 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