Entwickler-Ecke
Windows API - Lokaler Mousehook
Nersgatt - Do 20.01.11 11:20
Titel: Lokaler Mousehook
Moin,
ich verbrenne mir gerade das erste mal die Finger an einem Mousehook. Ich möchte einen lokalen Hook haben:
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: 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:
| var Hook : Cardinal = 0; function HookProc(nCode: Integer; MsgID: WParam; Data: LParam): LResult;
type TForm4 = class(TForm) mmo1: TMemo; procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private public end;
var Form4: TForm4;
implementation
{$R *.dfm}
procedure TForm4.FormCreate(Sender: TObject); begin Hook:=SetWindowsHookEx(WH_MOUSE,@HookProc,0,GetCurrentThreadID ); end;
procedure TForm4.FormDestroy(Sender: TObject); begin
UnhookWindowsHookEx(Hook); Hook:=0;
end;
procedure TForm4.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin mmo1.Lines.Add('MouseMove'); end;
function HookProc(nCode: Integer; MsgID: WParam; Data: LParam): LResult; begin if nCode < HC_ACTION then begin Result := CallNextHookEx(Hook, nCode, MsgID, Data); Exit; end else if nCode = HC_ACTION then begin Form4.mmo1.Lines.Add('MouseHook'); end;
Result := CallNextHookEx(Hook,nCode,MsgID,Data) ;
end; |
Das funktioniert auch teilweise. Allerdings tritt nach ein paar Sekunden eine Access Violation auf. Ich hab irgendwie überhaupt keine Idee, wo die Violation ausgelöst wird, und was der Grund dafür ist.
Wäre toll wenn ihr mir helfen könntet.
Danke!
Jens
Sinspin - Do 20.01.11 16:23
Versuch es mal mit MadExcept.
Ansonsten, ich vermute das die HookProc in ein anderen Thread läuft. Du solltest also auf dein Form Synchonized zugreifen oder ne Message senden die du auswertest um den Text zu schreiben.
Zudem ist deine HookProc etwas umständlich.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| function HookProc(nCode: Integer; MsgID: WParam; Data: LParam): LResult; begin if nCode = HC_ACTION then begin Form4.mmo1.Lines.Add('MouseHook'); end; Result := CallNextHookEx(Hook, nCode, MsgID, Data) ; end; |
So sollte es eigentlich reichen, denn CallNextHookEx wird ja in jedem Fall aufgerufen.
Nersgatt - Fr 21.01.11 09:06
Danke für die Antwort. Leider komm ich so auch nicht weiter. Ich hab mir jetzt ein User-Message gemacht und schicke der Form mit SendMessage diese Message in der HookProc. Trotzdem kommt es noch zu der AccessViolation.
Sinspin - Fr 21.01.11 13:15
Hm, hast du mal MadExcept installiert und es damit mal laufen lassen? MadExcept zeigt dir recht genau an wo es geknallt hat.
Nimm statt SendMessage mal PostMessage das entkoppelt den Nachrichtenversand noch ein bisschen mehr.
Nersgatt - Fr 21.01.11 13:22
Mit PostMessage ging es auch nicht. Mit MadExept muss ich mich erst mal befassen.
Martok - Fr 21.01.11 13:39
In einem MessageHook die MessageQueue verändern ist vielleicht auch nicht so die Idee des Tages...
Die richtige Calling Convention hast du aber, oder? Ich hab das grade mal ausprobiert, hier funktionierts wunderbar (auch wenn ich mysteriöse MouseMoves bekomme, ohne dass ich was angefasst hätte).
Delphi-Quelltext
1:
| function HookProc(nCode: Integer; MsgID: WParam; Data: LParam): LResult; stdcall; forward; |
Nersgatt - Fr 21.01.11 13:42
Martok hat folgendes geschrieben : |
| Die richtige Calling Convention hast du aber, oder? |
Ne, das war es! :zustimm:
Dankeschön!
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!