IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

Capturer le message BN_CLICKED d'une application externe


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2011
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 51
    Points : 50
    Points
    50
    Par défaut Capturer le message BN_CLICKED d'une application externe
    Bonjour à tous,
    j'essaye sans succès de surveiller un bouton dans une autre application.
    Je précise que je veux capturer le message Windows BN_CLICKED envoyé par le bouton a sa fenêtre parent.
    Le bouton est situé sur la form directement.

    En fait j'ai toujours 0 dans MMFData.NextHook. Le résultat du SetWindowsHookEx me donne toujours 0. Je capture bien un numéro d'ID du processus avec la fonction IDHandle que je visualise par les showmessage.
    L'ID du processus est celui du programme de lancement du hook 'progatester.exe' dans lequel j'ai mis un bouton Button2 pour déclencher le message.

    Je teste simplement le message WM_COMMAND dans un premier temps. Je verrai le reste après.

    Dites-moi si je me trompe:

    -je dois avoir une DLL Winhook.DLL liée a un processus (le processus est le fichier EXE qui contient la FORM qui contient le bouton que je veux Hooker)
    -le setwindowshookex doit se trouver dans Winhook.DLL
    -pour capturer BN_CLICKED je dois utiliser WH_CALLWNDPROC comme type de hook
    -Normalement, on capture le message WM_COMMAND et dans Hiword(Wparam) on récupère BN_CLICKED et dans Lparam le Handle du bouton.
    -la fonction de remplacement MsgFilterFunc doit se trouver dans Winhook.DLL
    -le setwindowshookex doit être:
    setwindowshookex(
    type de hook ici: WH_CALLWNDPROC,
    le nom de la fonction ici: MaWndProc,
    L'instance de Winhook.DLL ici: HInstance,
    l'ID du processus à Hooker ici: Idproc.th32ProcessID
    avec IdProc: TprocessEntry32 et IdProc.szExeFile := leprogahookerquicontientlebouton.exe
    -il faut partager certaines données comme le handle du hook parce que plusieurs instances de la DLL...
    comme c'est expliqué ici http://www.phidels.com/php/index.php...oks.htm&id=181

    Je penses avoir compris dans les grandes lignes mais il y a bien quelque chose que je ne capte pas !

    Merci d'avance pour les corrections que vous m'apporterez.

    voici le code de Winhook.DLL:
    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
    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
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
     
    library Winhook; 
     
    uses 
      Windows, Messages, SysUtils, dialogs, tlhelp32; 
     
    // Memory map file stuff 
     
    { 
      The CreateFileMapping function creates unnamed file-mapping 
      object for the specified file. 
    } 
    // Actual hook stuff 
     
    type 
      TPMsg = ^TMsg; 
     
    const 
      MMFName = 'MsgFilterHookDemo'; 
     
    type 
      PMMFData = ^TMMFData; 
      TMMFData = record 
        NextHook: HHOOK; 
        WinHandle: HWND; 
        MsgToSend: Integer; 
      end; 
     
      // global variables, only valid in the process which installs 
      //the hook. 
    var 
      MMFHandle: THandle; 
      MMFData: PMMFData; 
      IDProc: Tprocessentry32; 
      //processid,processhandle: cardinal; 
     
    function CreateMMF(Name: string; Size: Integer): THandle; 
    begin 
      Result := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, 
                    Size, PChar(Name)); 
      if Result <> 0 then 
      begin 
        if GetLastError = ERROR_ALREADY_EXISTS then 
        begin 
          CloseHandle(Result); 
          Result := 0; 
        end; 
      end; 
    end; 
     
    { The OpenFileMapping function opens a named file-mapping object. } 
     
    function OpenMMF(Name: string): THandle; 
    begin 
      Result := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 
                                PChar(Name)); 
      // The return value is an open handle to the specified 
      //file-mapping object. 
    end; 
     
    { 
     The MapViewOfFile function maps a view of a file into 
     the address space of the calling process. 
    } 
     
    function MapMMF(MMFHandle: THandle): Pointer; 
    begin 
      Result := MapViewOfFile(MMFHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0); 
    end; 
     
    { 
      The UnmapViewOfFile function unmaps a mapped view of a file 
      from the calling process's address space. 
    } 
     
    function UnMapMMF(P: Pointer): Boolean; 
    begin 
      Result := UnmapViewOfFile(P); 
    end; 
     
    function CloseMMF(MMFHandle: THandle): Boolean; 
    begin 
      Result := CloseHandle(MMFHandle); 
    end; 
     
     
     
    function UnMapAndCloseMMF: Boolean; 
    begin 
      Result := False; 
      if UnMapMMF(MMFData) then 
      begin 
        MMFData := nil; 
        if CloseMMF(MMFHandle) then 
        begin 
          MMFHandle := 0; 
          Result := True; 
        end; 
      end; 
    end; 
    //--------------------------------------------------------- 
    //fonction de remplacement pour le traitement du message 
    function MsgFilterFunc(Code: Integer; MwParam: integer; 
                        MlParam: integer): integer; stdcall; 
    var 
      MMFHandle: THandle; 
      MMFData: PMMFData; 
    begin 
      Result := 0; 
      MMFHandle := OpenMMF(MMFName); 
      if MMFHandle <> 0 then 
      begin 
        MMFData := MapMMF(MMFHandle); 
        if MMFData <> nil then 
        begin 
          if (Code < 0) or (MwParam = PM_NOREMOVE) then 
            Result := CallNextHookEx(MMFData.NextHook, Code, MwParam, 
                                    MlParam) 
          else 
          begin 
            if TPMsg(mlParam)^.message = WM_COMMAND then 
              showmessage(':WM_COMMAND:'); 
            Result := CallNextHookEx(MMFData.NextHook, Code, MwParam,MlParam); 
          end; 
          UnMapMMF(MMFData); 
        end; 
      CloseMMF(MMFHandle); 
      end; 
    end; 
    //--------------------------------------------------------- 
    //Trouve l'ID du processus du programme a surveiller 
    function IDHandle: cardinal; 
    var shothdl: Thandle; 
    begin 
      Result := 0; 
      IDProc.dwSize := sizeof(IDProc); 
      shothdl := createtoolhelp32snapshot(TH32CS_SNAPPROCESS, 0); 
      try 
        if shothdl=-1 then exit; 
        if process32first(shothdl,IDProc) then 
        begin 
          while process32next(shothdl,IDProc) do 
          begin 
            if ansisametext(IDProc.szExeFile,'progatester.exe') then 
            begin 
              result := IDProc.th32ProcessID; 
              showmessage('ok processus '+inttostr(result)); 
              break; 
            end; 
          end; 
        end; 
      finally 
        begin 
        closehandle(shothdl); 
        showmessage('ok processus '+inttostr(result)); 
        end; 
      end; 
    end; 
    //--------------------------------------------------------- 
    //Mise en place du hook avec WH_CALLWNDPROC pour interception 
    //des messages WM_COMMAND 
    function SetHook(WinHandle: HWND; MsgToSend: Integer): 
                      Boolean; stdcall; 
    begin 
      Result := False; 
      MMFHandle := 0; 
      MMFData  := nil; 
      if (MMFData = nil) and (MMFHandle = 0) then 
      begin 
        MMFHandle := CreateMMF(MMFName, SizeOf(TMMFData)); 
        if MMFHandle <> 0 then 
        begin 
          MMFData := MapMMF(MMFHandle); 
          if MMFData <> nil then 
          begin 
            MMFData.WinHandle := WinHandle; 
            MMFData.MsgToSend := MsgToSend; 
     
            MMFData.NextHook := SetWindowsHookEx(WH_CALLWNDPROC, 
                      MsgFilterFunc, HInstance,IDHandle); 
            showmessage(inttostr(MMFData.NextHook)); 
            if MMFData.NextHook = 0 then 
              UnMapAndCloseMMF 
            else 
              Result := True; 
          end 
          else 
          begin 
            CloseMMF(MMFHandle); 
            MMFHandle := 0; 
          end; 
        end; 
      end; 
    end; 
    //--------------------------------------------------------- 
    //Suppression du hook 
    function FreeHook: Boolean; stdcall; 
    begin 
      Result := False; 
      if (MMFData <> nil) and (MMFHandle <> 0) then 
        if UnHookWindowsHookEx(MMFData^.NextHook) then 
          Result := UnMapAndCloseMMF; 
    end; 
     
    exports 
      SetHook , 
      FreeHook ; 
    end.
    et voici le code de l'application lançant le hook

    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
     
    unit Uprogatester;
     
    interface
     
    uses
      Windows, Messages, SysUtils,Variants, Classes, Graphics,
      Controls, Forms, Dialogs, StdCtrls, tlhelp32,
      ExtCtrls;
    const
      HookDemo = 'WINHOOK.dll';
     
    const
      WM_HOOKCREATE = WM_USER + 300;
     
    type
      TForm2 = class(TForm)
        Button2: TButton;
        BTNSETHook: TButton;
        BTNUNSETHook: TButton;
        procedure BTNSETHookClick(Sender: TObject);
        procedure BTNUNSETHookClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        FHookSet: Boolean;
        procedure EnableButtons;
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form2: TForm2;
     
    function SetHook(WinHandle: HWND; MsgToSend: Integer): Boolean;
       stdcall; external HookDemo;
    function FreeHook: Boolean; stdcall; external HookDemo;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm2.BTNSETHookClick(Sender: TObject);
    begin
      FHookSet := LongBool(SetHook(Handle, WM_HOOKCREATE));
      EnableButtons;
    end;
     
    procedure TForm2.BTNUNSETHookClick(Sender: TObject);
    begin
      FHookSet := FreeHook;
      EnableButtons;
      BTNUNSETHook.Enabled := False;
     
    end;
     
    procedure TForm2.FormCreate(Sender: TObject);
    begin
      EnableButtons;
    end;
     
    procedure TForm2.FormDestroy(Sender: TObject);
    begin
      BTNUNSETHook.Click;
    end;
     
    procedure TForm2.EnableButtons;
    begin
      BtnSetHook.Enabled   := not FHookSet;
      BTNUNSETHook.Enabled := FHookSet;
    end;
     
    end.

  2. #2
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 685
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 685
    Points : 13 102
    Points
    13 102
    Par défaut
    Le fichier mappé ne sert à rien :
    • CallNextHookEx n'a plus besoin du handle de hook, la pile d'appel est gérée différemment depuis au moins Windows 2000.
    • FindWindow suffit pour retrouver ta fenêtre.
    • Le numéro du message n'a pas besoin d'être stocké non plus. Appelle plutôt RegisterWindowMessage côté exe et dll.
    • Le fichier mappé ne sera pas accessible pas une application de niveau d'intégrité inférieur, par exemple IE en mode protégé. Plantage de l'application.


    Attention, s'il y a un problème à l'ouverture du fichier mappé, le chaînage est interrompu. DeadLock assuré.

    SetWindowsHookEx attend le handle de la DLL et non de l'application cible. Si tu veux cibler une application précise, c'est par son thread que tu pourras.

    Quant au type de hook, WH_CALLWNDPROC (avant traitement par l'application cible, sinon WH_CALLWNDPROCRET) ou WH_GETMESSAGE.

  3. #3
    Membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2011
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 51
    Points : 50
    Points
    50
    Par défaut
    Bonjour AndNotOr,
    OK ! beaucoup de choses qui ne vont pas !
    Je prends en compte toutes les infos pour essayer de corriger le programme.
    Je poste dès que possible les modifications apportées

    Merci .

  4. #4
    Membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2011
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 51
    Points : 50
    Points
    50
    Par défaut
    Bon me revoilà,
    j'ai fait des modifications et maintenant la fonction setwindowshookex donne bien un Handle.
    Le handle de la DLL est donné par Getmodulehandle('winhook.dll).
    L'id du thread sur lequel je veux cibler le hook est donné dans la procédure IDHandle (ThreadID).

    Déjà, est-ce que les modifications apportées sont bonnes ?

    Normalement, quand je clique sur mon bouton 'Button2' je devrais déclencher un WM_COMMAND et donc entrer dans Msgfilterfunc mais la ce n'est pas le cas. Code vaut toujours 0.
    Ah oui si je mets un showmessage apres la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      if (Code < 0) or (MwParam = PM_NOREMOVE) then
    le programme génère une erreur de type: EOSError
    Un appel a une fonction du système d'exploitation a échouée.

    Merci de votre aide.

    La nouvelle DLL
    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
     
    { WINHOOK.dll }
    library Winhook;
     
    uses
      Windows, Messages, SysUtils, dialogs, tlhelp32;
     
    type
      TPMsg = ^TMsg;
     
    const
      MMFName = 'MsgFilterHookDemo';
     
    var
      NextHook: HHOOK;
     
    //---------------------------------------------------------
    //fonction de remplacement pour le traitement du message
    function MsgFilterFunc(Code: Integer; MwParam: integer;
                        MlParam: integer): integer; stdcall;
    begin
      Result := 0;
      if (Code < 0) or (MwParam = PM_NOREMOVE) then
        begin
        Result := CallNextHookEx(NextHook, Code, MwParam,
                                MlParam);
        end
      else
      begin
        if TPMsg(mlParam)^.message = WM_COMMAND then
          Result := CallNextHookEx(NextHook, Code, MwParam,MlParam);
      end;
    end;
    //---------------------------------------------------------
    //Mise en place du hook avec WH_CALLWNDPROC pour interception
    //des messages WM_COMMAND
    function SetHook(HDLL: HWND;th: integer; MsgToSend: Integer):
                       Boolean; stdcall;
    begin
      Result := False;
      NextHook := SetWindowsHookEx(WH_CALLWNDPROC,
                MsgFilterFunc, HDLL,TH);
     
      if NextHook <> 0 then Result := True;
    end;
    //---------------------------------------------------------
    //Suppression du hook
    function FreeHook: Boolean; stdcall;
    begin
      Result := False;
      if UnHookWindowsHookEx(NextHook) then
        Result := true;
    end;
     
    exports
      SetHook ,
      FreeHook ;
     
    begin
    end.
    et le programme de lancement du hook
    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
    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
     
    unit Uprogatester;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics,
      Controls, Forms, Dialogs, StdCtrls, tlhelp32,
      ExtCtrls;
    const
      HookDemo = 'WINHOOK.dll';
     
    const
      WM_HOOKCREATE = WM_USER + 300;
     
    type
      TForm2 = class(TForm)
        Button2: TButton;
        BTNSETHook: TButton;
        BTNUNSETHook: TButton;
        Edit1: TEdit;
        procedure BTNSETHookClick(Sender: TObject);
        procedure BTNUNSETHookClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure IDHandle;
      private
        FHookSet: Boolean;
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form2: TForm2;
      IDProc: Tprocessentry32;
      IDThr: Tthreadentry32;
      processid,processhandle,threadid: cardinal;
     
    function SetHook(HDLL: hwnd; IDTh: integer; MsgToSend: Integer): Boolean;
       stdcall; external HookDemo;
    function FreeHook: Boolean; stdcall; external HookDemo;
     
    implementation
     
    {$R *.dfm}
    //------------------------------------------------------
    //Bouton Hook
    procedure TForm2.BTNSETHookClick(Sender: TObject);
    var HDLL : Hwnd;
    begin
      idhandle;
      HDLL := getmodulehandle('winhook.dll');
      FHookSet := LongBool(SetHook(HDLL,ThreadID, WM_HOOKCREATE));
    //  EnableButtons;
      if FHookSet then
      begin
        BTNSETHook.Enabled   := false;
        BTNUNSETHook.Enabled := true;
      end;
    end;
    //------------------------------------------------------
    //Bouton UNHook
    procedure TForm2.BTNUNSETHookClick(Sender: TObject);
    begin
      FHookSet := FreeHook;
      if FHookSet then
      begin
        BTNSETHook.Enabled   := true;
        BTNUNSETHook.Enabled := false;
      end;
    end;
    //------------------------------------------------------
    //Recherche handle ID processus et thread
    procedure TForm2.IDHandle;
    var shothdl: Thandle;
    begin
    //pour trouver une numero de handle et d'id d'un processus
    IDProc.dwSize := sizeof(IDProc);
    shothdl := createtoolhelp32snapshot(TH32CS_SNAPPROCESS, 0);
    try
      if shothdl=-1 then exit;
      if process32first(shothdl,IDProc) then
      begin
        while process32next(shothdl,IDProc) do
        begin
          if ansisametext(IDProc.szExeFile,'progatester.exe') then
          begin
            processid := IDProc.th32ProcessID;
            processhandle := openprocess(
                PROCESS_ALL_ACCESS,false,processid);
            if processhandle <>0 then
              break;
          end;
        end;
      end;
    finally closehandle(shothdl);
    end;
     
    //pour trouver un numero d'id d'un thread
    IDThr.dwSize := sizeof(IDThr);
    shothdl := createtoolhelp32snapshot(TH32CS_SNAPTHREAD, 0);
    try
      if shothdl=-1 then exit;
      if thread32first(shothdl,IDThr) then
      begin
        while thread32next(shothdl,IDThr) do
        begin
          if IDThr.th32OwnerProcessID=processid then
          begin
            threadid := IDThr.th32ThreadID;
          end;
        end;
      end;
    finally closehandle(shothdl);
    end;
    end;
    //------------------------------------------------------
    procedure TForm2.FormCreate(Sender: TObject);
    begin
    FHookSet := false;
    //  EnableButtons;
    btnsethook.Enabled := true;
    btnunsethook.Enabled := false;
    end;
    //------------------------------------------------------
    procedure TForm2.FormDestroy(Sender: TObject);
    begin
      BTNUNSETHook.Click;
    end;
     
     
    end.

  5. #5
    Membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2011
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 51
    Points : 50
    Points
    50
    Par défaut
    Ah, je viens de m'aperçevoir que dans le code que j'ai posté je ne fais rien si message = wm_command. J'ai enlevé le showmessage mais peu importe.

  6. #6
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 685
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 685
    Points : 13 102
    Points
    13 102
    Par défaut
    Les boucles suite aux createtoolhelp32snapshot sont fausses.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if Process32First(...) then
    repeat
      ...
    until not Process32Next(...);
    Tu peux aussi ne créer qu'un seul snapshot pour les deux boucles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    shothdl := createtoolhelp32snapshot(TH32CS_SNAPPROCESS or TH32CS_SNAPTHREAD, 0);
    Pourquoi OpenProcess ?
    Mais avant de cibler un thread précis, commence par tout le système.

    Pas besoin de chercher le handle de la dll depuis l'exe. Simplement utiliser hInstance dans la dll.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SetWindowsHookEx(WH_CALLWNDPROC, MsgFilterFunc, hInstance, TH);
    Last but not least, le callback d'un hook WH_CALLWNDPROC retourne une structure TCWPStruct et non TMsg

  7. #7
    Membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2011
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 51
    Points : 50
    Points
    50
    Par défaut
    J'ai enlevé la partie openprocess qui n'avait pas lieu d'être effectivement, et j'ai changé les boucles ce qui devient:
    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
    //Recherche ID processus et thread
    procedure TForm2.IDHandle;
    var shothdl: Thandle;
    begin
    //pour trouver une numero d'id d'un processus et Thread
    IDProc.dwSize := sizeof(IDProc);
    shothdl := createtoolhelp32snapshot(TH32CS_SNAPPROCESS, 0);
    try
      if shothdl=-1 then exit;
      if process32first(shothdl,IDProc) then
      begin
        Repeat 
          if ansisametext(IDProc.szExeFile,'progatester.exe') then
            processid := IDProc.th32ProcessID;
        Until process32next(shothdl,IDProc);
      end;
    finally closehandle(shothdl);
    end;
     
    //pour trouver un numero d'id d'un thread
    IDThr.dwSize := sizeof(IDThr);
    shothdl := createtoolhelp32snapshot(TH32CS_SNAPTHREAD, 0);
    try
      if shothdl=-1 then exit;
      if thread32first(shothdl,IDThr) then
      begin
        Repeat 
          if IDThr.th32OwnerProcessID=processid then
            threadid := IDThr.th32ThreadID;
        Until thread32next(shothdl,IDThr);
      end;
    finally closehandle(shothdl);
    end;
    end;
    On utilise donc plus pour le moment cette procedure 'IDHandle' vu que le hook doit être système (=0)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    NextHook := SetWindowsHookEx(WH_CALLWNDPROC,
                MsgFilterFunc, Hinstance,0);
    J'ai changé le Type TMSg par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type
      TPMsg = ^TCWPStruct;
    La fonction MsgFilterFunc est bien appelée mais MWParam est toujours à 0 ce qui me fait passer dans la condition PM_NOREMOVE et Code est toujours 0 également.
    Par contre, TPMsg(mlParam)^.message prend la valeur 8 puis alterne entre 647, 641.
    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
    //fonction de remplacement pour le traitement du message
    function MsgFilterFunc(Code: Integer; MwParam: integer;
                        MlParam: integer): integer; stdcall;
    begin
      Result := 0;
      if (Code < 0) or (MwParam = PM_NOREMOVE) then
        begin
        Result := CallNextHookEx(NextHook, Code, MwParam,
                                MlParam);
        end
      else
      begin
        if TPMsg(mlParam)^.message = WM_COMMAND then
          begin
          sendmessage(findwindow('TForm2','Programme a tester'),WM_SETTEXT,0,
                  integer(pchar('OK')));
          Result := CallNextHookEx(NextHook, Code, MwParam,MlParam);
          end;
      end;
    end;
    Je change le texte de la fenetre la première fois que j'ai WM_COMMAND pour voir si le hook marche.
    Je ne vois toujours pas ce qui ne va pas I'm very bad.
    Merci de ta patience !

  8. #8
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 685
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 685
    Points : 13 102
    Points
    13 102
    Par défaut
    Le problème est que tu ne lis pas assez la doc !

    Chaque type de hook reçoit des informations qui lui sont propres. WParam est bien le type de lecture par PeekMessage (ex. PM_NOREMOVE) dans le cas d'un hook WH_GETMESSAGE mais pour un type WH_CALLWNDPROC, WParam renseigne si l'appel est passé depuis le thread courant ou non. Donc rien à voir

    Le code à "0" (HC_ACTION) est correct si un traitement doit être effectué.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function CallWndProc(Code: Integer; wParam :WPARAM; lParam: LPARAM): LResult; stdcall;
    begin
      if Code = HC_ACTION then
      begin
        if PCWPStruct(lParam)^.message = WM_COMMAND then
          ...
      end;
     
      Result := CallNextHookEx(0, Code, WParam, LParam);
    end;
    Si tu n'interceptes toujours pas WM_COMMAND, et bien c'est que WH_CALLWNDPROC n'est pas le bon type de hook

  9. #9
    Membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2011
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 51
    Points : 50
    Points
    50
    Par défaut
    Effectivement, j'avais lu ce que disait la MSDN mais un peu trop vite et je n'ai pas fait attention.
    C'est très bien de m'avoir fait chercher comme ça. J'ai appris beaucoup de choses notamment qu'il faut lire la DOC ! et pas une ligne sur deux comme j'ai pu le faire.

    Merci de ta patience à mon égard.

    You're the best. It works very well !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 12
    Dernier message: 23/01/2008, 09h17
  2. Réponses: 2
    Dernier message: 02/08/2006, 19h55
  3. Fermer une application externe
    Par jean tof dans le forum C++Builder
    Réponses: 2
    Dernier message: 02/05/2006, 16h18
  4. Réponses: 6
    Dernier message: 07/09/2005, 20h31
  5. [Excel] Utiliser une application externe par une macro
    Par thierry2.dlp dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 09/08/2005, 22h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo