Dans une DLL, je cherche à sous-classer une fenêtre (le handle est connu) dans le même processus. Or, en utilisant SetWindowLong avec le paramètre GWL_WNDPROC, je reçois une violation d'accès. J'ai essayé aussi de sous-classer globalement en utilisant SetClassLongA avec le peramètre GCLP_WNDPROC, et il n'y a aucune réaction apparente, mais pas d'erreur. Je sais qu'avec SetClassLongA, l'effet ne sera visible que pour des fenêtres créées APRES l'appel de la fonction, alors qu'avec SetWindowLog, l'effet devrait se produire sur la fenêtre spécifiée par le handle. J'ai vérifié ma fonction nommée "essai" est appelée correctement par le programme application. Le handle de la fenêtre est valide.

Ah oui, le but de tout cela est d'intercepter le message WM_CLOSE sur une fenêtre du même processus, mais non initiée par ma DLL. Je n'ai aucun contrôle sur cette fenêtre autrement qu'en sous-classant la procedure WndProc. J'utilise Delphi 6 Personal V6.0 (build 6.163), sous XP SP3.

Pourriez-vous m'aider avec ce code, svp ?

Voilà mon code:
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
 
library test;
 
uses
  Windows
  ,Sysutils
  ,Classes
  ,Messages
//  ,Dialogs   
;
 
var
   pOldWinProc: Pointer;
 
function NewWinProc(hWnd: HWND; Msg: WORD; wParam: WORD; lParam: LONGINT): LONGINT; stdcall; export;
var
   MessageProcessed: Boolean;
begin
   MessageProcessed := False;
   case Msg of
     WM_CLOSE: begin
         beep;
         MessageProcessed := True;
     end;
      { if you process a message then set MessageProcessed to True }
   end; {end of case Msg }
   if not MessageProcessed then
      Result := CallWindowProc(pOldWinProc,hWnd,Msg,wParam,lParam)
   else
      Result := 0;
end;
 
 
function essai(const phnd,oldhnd,id: integer ): integer; stdcall; export;
var
        wnd: hWnd;
 
const
        GCLP_WNDPROC = -24;
 
begin
        wnd := phnd;
 
// enable one of the 2 following lines :
// following line will cause a fault
        pOldWinProc := Pointer(SetWindowLong(Wnd, GWL_WNDPROC, LongInt(@NewWinProc)));
// following line seems to do nothing...
//          pOldWinProc := Pointer(SetClassLongA(Wnd,GCLP_WNDPROC,LongInt(@NewWinProc)));
        result := longint(pOldWinProc);
end;
 
exports
    essai
    ,NewWinProc
;
 
begin
end.
EDIT

J'ai cru bien faire en mettant mon post en français et en anglais - je ne recommencerai pas et je m'en excuse auprès de ceux qui en on t pris ombrage.