Je suis en train d'essayer de faire un hook (clavier et souris) avec Delphi 2010, mais j'obtiens une violation d'accès (j'ai déjà fait des hook clavier, sans problème avec Delphi 6).
Voici ma DLL :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 library DLLHook; uses Windows, UnitFonctions in 'UnitFonctions.pas'; {$R *.res} begin _nFInstance := HInstance; _nMemPartagee := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(TDonnees), 'Hooks clavier souris'); _VueDonnees := MapViewOfFile(_nMemPartagee, FILE_MAP_WRITE, 0, 0, 0); end.Et voici l'application appelante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 unit UnitFonctions; interface uses Windows, Messages; const WM_CLAVIER = WM_APP + 1; WM_SOURIS = WM_APP + 2; type TDonnees = record KeyboarddHookHandle: HHOOK; // Handle du hook du clavier. MouseHookHandle: HHOOK; // Handle du hook de la souris. InfoSouris: MOUSEHOOKSTRUCT; hDestWindow: HWND; end; PDonnees = ^TDonnees; procedure InitHook(hDest : HWND); export; stdcall; function KeyboardProc(nCode, wParam, lParam: Integer): Integer; stdcall; function MouseProc(nCode, wParam, lParam: Integer): Integer; stdcall; procedure EndHook; export; stdcall; procedure UnloadLibrary; export; stdcall; var _nFInstance: Cardinal; // Handle d'instance de la DLL. _nMemPartagee: Cardinal; // Handle de la zone de mémoire partagée. _VueDonnees: PDonnees; // Pointeur vers la zone de mémoire. implementation procedure InitHook(hDest: HWND); begin _VueDonnees^.KeyboarddHookHandle := SetWindowsHookEx(WH_KEYBOARD, @KeyboardProc, _nFInstance, 0); _VueDonnees^.MouseHookHandle := SetWindowsHookEx(WH_MOUSE, @MouseProc, _nFInstance, 0); _VueDonnees^.hDestWindow := hDest; end; function KeyboardProc(nCode, wParam, lParam: Integer): Integer; begin if nCode >= 0 then begin PostMessage(_VueDonnees^.hDestWindow, WM_CLAVIER, wParam, lParam); end; Result := CallNextHookEx(_VueDonnees^.KeyboarddHookHandle, nCode, wParam, lParam); end; function MouseProc(nCode, wParam, lParam: Integer): Integer; begin if nCode >= 0 then begin // Si clic-gauche. if(wParam = WM_LBUTTONDOWN) then begin _VueDonnees.InfoSouris := PMouseHookStruct(lParam)^; // Récupère les infos. PostMessage(_VueDonnees^.hDestWindow, WM_SOURIS, wParam, LongInt(@_VueDonnees.InfoSouris)); end; end; Result := CallNextHookEx(_VueDonnees^.MouseHookHandle, nCode, wParam, lParam); end; procedure EndHook; begin // Supression des hooks. UnhookWindowsHookEx(_VueDonnees^.KeyboarddHookHandle); UnhookWindowsHookEx(_VueDonnees^.MouseHookHandle); end; procedure UnloadLibrary; begin UnmapViewOfFile(_VueDonnees); CloseHandle(_nMemPartagee); end; end.J'obtiens une violation d'accès au moment de l'appel InitHooks.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 private _nHInstDLL: Cardinal; _bHook: Boolean; _InitHooks: procedure(hDest: HWND); stdcall; _EndHooks: procedure; stdcall; _UnloadLibrary: procedure; stdcall; procedure EvenementClavier(var P: TWMKey); message WM_CLAVIER; procedure EvenementSouris(var P: TWMMouse); message WM_SOURIS; public { Déclarations publiques } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin _bHook := False; _nHInstDLL := LoadLibrary(PChar(ExtractFilePath(Application.ExeName) + 'DLLHook.dll')); if _nHInstDLL = 0 then Application.MessageBox(PChar('Erreur : le chargement de la DLL (DLLHook.dll) a échoué !' + #13#10 + SysErrorMessage(GetLastError)), PChar(Caption + ' - erreur'), MB_ICONERROR + MB_OK) else begin _InitHooks := GetProcAddress(_nHInstDLL, 'InitHook'); _EndHooks := GetProcAddress(_nHInstDLL, 'EndHook'); _UnloadLibrary := GetProcAddress(_nHInstDLL, 'UnloadLibrary'); _bHook := True; if _nHInstDLL <> 0 then _InitHooks(Form1.Handle); end; end; procedure TForm1.EvenementClavier(var P: TWMKey); begin Memo.Lines.Add('Clavier :'); end; procedure TForm1.EvenementSouris(var P: TWMMouse); begin Memo.Lines.Add('Souris :'); end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin if _bHook then _EndHooks; if _nHInstDLL <> 0 then begin _UnloadLibrary; FreeLibrary(_nHInstDLL); end; end;
Par contre SetWindowsHookEx et MapViewOfFile ont été exécuté sans erreur.
Qu'est ce que j'ai mal fait ?
Partager