| Autor |
Beitrag |
noNeed 4 aNick
      
Beiträge: 20
|
Verfasst: Di 12.07.05 19:30
Hi zusammen,
da ich im Moment in den meisten meiner Projekte lokale Hooks verwende und gerade Lust hatte,
wollte ich ne Klasse für meine lokalen Hooks entwickeln.
Folgendes is dabei meinem wahnsinnigen Geist entsprungen
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122:
| unit LocalHook;
interface
uses Windows, SysUtils, Classes;
type
TLocalHook = class(TPersistent) private HookInstalled: boolean; HookType: Integer;
procedure InstallHook; procedure UnInstallHook;
function RealHookProc(Code: integer; wParam: word; lParam: longword): longword; stdcall; public HookID: HHook; constructor Create(AType: Integer = 0); destructor Destroy;
procedure setHookType(AType: Integer); procedure Activate; procedure Deactivate;
procedure HookProc(Code: integer; wParam: word; lParam: longword); virtual; function Active: boolean; end;
implementation
constructor TLocalHook.Create(AType: Integer = 0); begin inherited Create;
HookInstalled := false;
setHookType(AType); end;
destructor TLocalHook.Destroy; begin if HookInstalled then UnInstallHook;
inherited Destroy; end;
procedure TLocalHook.setHookType(AType: Integer); var tmp: boolean; begin tmp := HookInstalled;
if HookInstalled then UnInstallHook;
HookType := AType;
if tmp then InstallHook; end;
function TLocalHook.RealHookProc(Code: integer; wParam: word; lParam: longword): longword; stdcall; begin if code < HC_ACTION then begin Result := CallNextHookEx(HookID, Code, wParam, lParam); exit; end;
HookProc(Code, wParam, lParam);
Result := CallNextHookEx(HookID, Code, wParam, lParam); end;
procedure TLocalHook.HookProc(Code: integer; wParam: word; lParam: longword); begin
end;
procedure TLocalHook.InstallHook; begin if HookType <= 0 then exit;
if HookInstalled then UnInstallHook;
HookID := SetWindowsHookEx( HookType, @RealHookProc, 0, GetCurrentThreadID() );
HookInstalled := (HookID <> 0); end;
procedure TLocalHook.UnInstallHook; begin if not HookInstalled then exit;
HookInstalled := not UnhookWindowsHookEx(HookID); end;
function TLocalHook.Active: boolean; begin Result := HookInstalled; end;
procedure TLocalHook.Activate; begin InstallHook; end;
procedure TLocalHook.Deactivate; begin UnInstallHook; end;
end. |
Das Ganze wird bzw soll dann folgendermaßen aufgerufen werden:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| THook = class(TLocalHook) public procedure HookProc(Code: integer; wParam: word; lParam: longword); override; end;
procedure THook.HookProc(Code: integer; wParam: word; lParam: longword); type PMsg = ^TMsg; var msg: PMsg; begin msg := PMsg(lParam);
if msg^.message = WM_KEYDOWN then begin ShowMessage('Hello World'); end; end;
Hook := THook.Create(WH_GETMESSAGE); Hook.Activate;
|
Wenn ich das Ganze jetzt aber compilen möchte kommt in dieser Zeile nen Fehler:
Delphi-Quelltext 1:
| HookID := SetWindowsHookEx( HookType, @RealHookProc, 0, GetCurrentThreadID() ); |
| Delphi Debugger hat folgendes geschrieben: |
[Fehler] LocalHook.pas(94): Variable erforderlich
|
Was kann ich da jetzt tun??
ThxinAdv
Alex
Zuletzt bearbeitet von noNeed 4 aNick am Di 12.07.05 19:55, insgesamt 1-mal bearbeitet
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 12.07.05 19:41
Durch diese Formatierung blickst du durch?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure THook.HookProc(Code: integer; wParam: word; lParam: longword); type PMsg = ^TMsg; var msg: PMsg; begin msg := PMsg(lParam);
if msg^.message = WM_KEYDOWN then begin ShowMessage('Hello World'); end; end; |
Ich würde fast wetten in diser chaotischen Formatierung verbirgt sichd er Fehler.
Da wird wohl irgendwo eine Variable erwartet aber du hast da ein Konstante oder so.
|
|
noNeed 4 aNick 
      
Beiträge: 20
|
Verfasst: Di 12.07.05 19:52
Luckie hat folgendes geschrieben: |
Durch diese Formatierung blickst du durch?
Ich würde fast wetten in diser chaotischen Formatierung verbirgt sichd er Fehler.
|
1.) Ja, warum auch nicht?
2.) Um wieviel? Ich wette gerne, wenn ich weiß, dass ich gewinne
Abgesehen von der 'Type Zeile', die eingefügt hatte und die dadurch noch ne auf einen anderen Typebereich passende
Leerzeichen-Anzahl hat, halte ich das Ganze für recht übersichtlich.
Es sei denn du hast ne Auflösung @ ca. 640x480. Dann wird's zugegebenermaßen eng..
Weiterhin glaube ich, dass an dem schönen Spruch 'Nur Kleingeister halten Ordnung, Genies überblicken das Chaos' was Wahres dran ist ;P
Luckie hat folgendes geschrieben: |
Da wird wohl irgendwo eine Variable erwartet aber du hast da ein Konstante oder so.
|
Glaube ich nicht.
@RealHookProc macht das Problem und SetWindowsHookExt rufe ich sonst immer auch mit nem Pointer auf ne Funktion auf.
Ich denke das Problem ist, dass RealHookProc eine Funktion einer Klasse (TLocalHook) ist. Denn wenn ich sie außerhalb der Klasse definiere, funktioniert der Code bzw es gibt nen Fehler, weil die HookID, die ich in der Funktion verwende undefiniert ist.
Problem ist also, dass ich auf die HookID, die ich in dieser Funktion ja brauche nicht mehr zugreifen kann, da die RealHookProc außerhalb ihrer Klasse nicht weiß, welcher Variable/Klasse sie angehört.
Ich hoffe ich konnte das einigermaßen verständlich erklären...
|
|
Muetze1
      
Beiträge: 346
|
Verfasst: Di 12.07.05 20:44
Moin!
Grundlegend sehe ich hier das Problem, das die WinAPI Funktion eine Procedure haben will und man eine Methode übergibt. Eine Methode hat aber einen versteckten Self-Parameter was die Nutzung bei er WinAPI Funktion ausschliesst. Auch sehe ich das Problem der Überschreibbarkeit der Methode, wodurch die einfache Angabe einer Adresse der Methode in der Klasse nicht möglich sein sollte. Daher wahrscheinlich auch die Fehlermeldung.
Grundlegend muss eine Procedure der WinAPI übergeben werden. Diese sollte aber zur Methode umgemünzt werden, damit es in der Klasse klappt. Nun ist das gleiche Problem bei der WndProc() von der VCL auch gelöst worden. Grundlegend muss eine Methode an die WinAPI gegeben werden, die VCL schafft es trotzdem dies in eine Methode umzubiegen. Daher nun die Frage: Wer kann Details dazu liefern und sagen wie man es macht?
MfG
Muetze1
_________________ 49 63 68 68 61 62 65 6B 65 69 6E 65 41 68 6E 75 6E 67 21
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Di 12.07.05 22:49
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
noNeed 4 aNick 
      
Beiträge: 20
|
Verfasst: Mi 13.07.05 00:43
Hi BenBE, MakeObjectInstance ist leider nur für WndProcs gedacht, daher kann ich ihr meine HookProc nicht übergeben...
Hab aber mit Motzi und durch SwissDelphiCenter (...Methodenzeiger in Funktionszeiger konvertieren?) diese Lösung rausbekommen:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164:
| unit LocalHook;
interface
uses Windows, SysUtils, Classes;
type
THookProc = function(Code: integer; wParam: word; lParam: longword):longword of object; stdcall;
TLocalHook = class(TPersistent) private HookInstalled: boolean; HookType: Integer; PRealHookProc: Pointer; HookID: HHook;
procedure InstallHook; procedure UnInstallHook;
function MakeProcInstance(H: THookProc): Pointer; procedure FreeProcInstance(ProcInstance: Pointer);
function RealHookProc(Code: integer; wParam: word; lParam: longword): longword; stdcall; public constructor Create(AType: Integer = 0); destructor Destroy;
procedure setHookType(AType: Integer); procedure Activate; procedure Deactivate;
procedure HookProc(Code: integer; wParam: word; lParam: longword); virtual; function Active: boolean; end;
implementation
constructor TLocalHook.Create(AType: Integer = 0); begin inherited Create;
HookInstalled := false;
setHookType(AType); end;
destructor TLocalHook.Destroy; begin if HookInstalled then UnInstallHook;
inherited Destroy; end;
procedure TLocalHook.setHookType(AType: Integer); var tmp: boolean; begin tmp := HookInstalled;
if HookInstalled then UnInstallHook;
HookType := AType;
if tmp then InstallHook; end;
function TLocalHook.RealHookProc(Code: integer; wParam: word; lParam: longword): longword; stdcall; begin if code < HC_ACTION then begin Result := CallNextHookEx(HookID, Code, wParam, lParam); exit; end;
HookProc(Code, wParam, lParam);
Result := CallNextHookEx(HookID, Code, wParam, lParam); end;
procedure TLocalHook.HookProc(Code: integer; wParam: word; lParam: longword); begin
end;
procedure TLocalHook.InstallHook; begin if HookType <= 0 then exit;
if HookInstalled then UnInstallHook;
PRealHookProc := MakeProcInstance(RealHookProc);
HookID := SetWindowsHookEx( HookType, PRealHookProc, 0, GetCurrentThreadID() );
HookInstalled := (HookID <> 0); end;
procedure TLocalHook.UnInstallHook; begin if not HookInstalled then exit;
HookInstalled := not UnhookWindowsHookEx(HookID); end;
function TLocalHook.Active: boolean; begin Result := HookInstalled; end;
procedure TLocalHook.Activate; begin InstallHook; end;
procedure TLocalHook.Deactivate; begin UnInstallHook; FreeProcInstance(PRealHookProc); end;
function TLocalHook.MakeProcInstance(H: THookProc): Pointer; var M: TMethod; begin M := TMethod(H);
GetMem(Result, 15);
asm MOV BYTE PTR [EAX], $B9 MOV ECX, M.Data MOV DWORD PTR [EAX+$1], ECX MOV BYTE PTR [EAX+$5], $5A MOV BYTE PTR [EAX+$6], $51 MOV BYTE PTR [EAX+$7], $52 MOV BYTE PTR [EAX+$8], $B9 MOV ECX, M.Code MOV DWORD PTR [EAX+$9], ECX MOV BYTE PTR [EAX+$D], $FF MOV BYTE PTR [EAX+$E], $E1 end; end;
procedure TlocalHook.FreeProcInstance(ProcInstance: Pointer); begin FreeMem(ProcInstance, 15); end;
end. |
Danke nochmal an Alle
Bye
Alex
|
|
|