Hook WH_CBT

Partagez votre expérience de PureBasic avec les autres utilisateurs.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Hook WH_CBT

Message par nico »

Voici une Dll et son Appli qui permettent de récupérer facilement plusieurs informations concernant la création, le déplacement et la destruction de Fenêtres de tous les Processus.

Une fois la Dll compilée, faire fonctionner le Prog dans l'éditeur en mode Debug.


La DLL avec pour nom et chemin "C:\CBTHook.dll" :

Code : Tout sélectionner

Structure Partage
  Hook.l
  Hwnd.l
  Donnee1.l
  Donnee2.l
  Donnee3.l
  Donnee4.l
  Donnee5.l
EndStructure

Global MemoirePartagee,*VueDonnees.Partage

#WM_MONMESSAGE=111

Procedure CbtHook(nCode,wParam,lParam) 
  If nCode < 0 
    ProcedureReturn CallNextHookEx_(Hook,nCode,wParam,lParam) 
  Else

    Select nCode
      Case #HCBT_ACTIVATE
        *Activate.CBTACTIVATESTRUCT=lParam
        *VueDonnees\Donnee1=wParam
        *VueDonnees\Donnee2=*Activate\fMouse
        
      Case #HCBT_CLICKSKIPPED
          ;Ici je ne traite pas
       
      Case #HCBT_CREATEWND 
          *VueDonnees\Donnee1=wParam
          
      Case #HCBT_DESTROYWND 
          *VueDonnees\Donnee1=wParam
        
      Case #HCBT_KEYSKIPPED 
          *VueDonnees\Donnee1=wParam
        
      Case #HCBT_MINMAX
          *VueDonnees\Donnee1=wParam
          *VueDonnees\Donnee2=lParam & $FFFF
         
      Case #HCBT_MOVESIZE
          *Rect.RECT=lParam
          *VueDonnees\Donnee1=wParam
          *VueDonnees\Donnee2=*Rect\left
          *VueDonnees\Donnee3=*Rect\top
          *VueDonnees\Donnee4=*Rect\right
          *VueDonnees\Donnee5=*Rect\bottom
        
      Case #HCBT_QS 
        ;Ici je ne traite pas 
        
      Case #HCBT_SETFOCUS
          *VueDonnees\Donnee1=wParam 
      
      Case #HCBT_SYSCOMMAND 
        ;Ici je ne traite pas 
    EndSelect
     
  EndIf
  
  SendMessage_(*VueDonnees\Hwnd, #WM_MONMESSAGE, nCode, 0)
  
  ProcedureReturn CallNextHookEx_(Hook,nCode,wParam,lParam) 
EndProcedure 


ProcedureDLL AttachProcess(Instance)
  MemoirePartagee=CreatefileMapping_($FFFFFFFF,#NULL, #PAGE_READWRITE, 0, SizeOf(Partage),"Mapping")
  *VueDonnees=MapViewOfFile_(MemoirePartagee, #FILE_MAP_WRITE, 0, 0, 0)
EndProcedure

ProcedureDLL DetachProcess(Instance)
  UnmapViewOfFile_(VueDonnees)
  CloseHandle_(MemoirePartagee)
EndProcedure
 
ProcedureDLL AttachThread(Instance)
EndProcedure
  
ProcedureDLL DetachThread(Instance)
EndProcedure
  
ProcedureDLL Initialiser_Hook(Handle,Hinst)
  *VueDonnees\Hwnd=Handle
  Hook = SetWindowsHookEx_(#WH_CBT,@CbtHook(),Hinst,0) 
  If Hook = #FALSE 
    MessageRequester("","Echec du Hook") 
    ProcedureReturn 0 
  EndIf
  *VueDonnees\Hook=Hook
  ProcedureReturn *VueDonnees
EndProcedure   


ProcedureDLL Fermeture_Hook()
  UnhookWindowsHookEx_(*VueDonnees\Hook)
  ProcedureReturn 1
EndProcedure

Le Prog:

Code : Tout sélectionner

#Librairie=0
#WM_MONMESSAGE=111

Structure Partage2
  Hook.l
  Hwnd.l
  Donnee1.l
  Donnee2.l
  Donnee3.l
  Donnee4.l
  Donnee5.l
EndStructure

Global *Vue.Partage2

Procedure ProcedureCallback(WindowID, Message, wParam, lParam) 
  Resultat = #PB_ProcessPureBasicEvents 
  Select Message
    Case #WM_MONMESSAGE
      Select wParam
        Case #HCBT_ACTIVATE
          Debug "---HCBT_ACTIVATE---"           ;Une Fenêtre est Active
          Debug "Handle= "+Str(*Vue\Donnee1)    ;Handle de la Fenêtre Active
          Debug "Souris= "+Str(*Vue\Donnee2)    ;Fenêtre activée par la Souris =1 , sinon=0
          Debug "-------------------"
          
        Case #HCBT_CLICKSKIPPED                 
          ;Ici je ne traite pas
          
        Case #HCBT_CREATEWND
          Debug "---HCBT_CREATEWND---"          ;Une Fenêtre est Créée
          Debug "Handle= "+Str(*Vue\Donnee1)    ;Handle de la fenêtre créée 
          Debug "-------------------"
          
        Case #HCBT_DESTROYWND 
          Debug "---HCBT_DESTROYWND---"         ;Une Fenêtre est Détruite
          Debug "Handle= "+Str(*Vue\Donnee1)    ;Handle de la fenêtre détruite 
          Debug "-------------------"
          
        Case #HCBT_KEYSKIPPED                   ;/Je ne sais pas dans quelle condition, on reçoit ce message                 
          Debug "---HCBT_KEYSKIPPED---"         ;Une Touche est frappée
          Debug *Vue\Donnee1                    ;Code de la Touche
          Debug "-------------------"
          
        Case #HCBT_MINMAX
          Debug "---HCBT_MINMAX---"             ;Une Fenêtre est Minimisée ou Maximisée
          Debug "Handle= "+Str(*Vue\Donnee1)    ;Handle de la Fenêtre
          Debug "SW_****= "+Str(*Vue\Donnee2)   ;Contient une valeur de la fonction ShowWindow
          Debug "-------------------"           ;Minimisé=6,Maximisé=3,Restauré=9,Caché=0;Montré=5
          
        Case #HCBT_MOVESIZE                       
          Debug "---HCBT_MOVESIZE---"           ;Une Fenêtre est déplacée ou redimensionnée
          Debug "Handle= "+Str(*Vue\Donnee1)    ;Handle de la Fenêtre
          Debug "Left= "+Str(*Vue\Donnee2)      ;left
          Debug "Top= "+Str(*Vue\Donnee3)       ;top
          Debug "Right= "+Str(*Vue\Donnee4)     ;right
          Debug "Bottom= "+Str(*Vue\Donnee5)    ;bottom
          Debug "-------------------"
          
        Case #HCBT_QS 
          ;Ici je ne traite pas 
          
        Case #HCBT_SETFOCUS
          Debug "---HCBT_SETFOCUS---"           ;Une Fenêtre a le focus clavier
          Debug "Handle= "+Str(*Vue\Donnee1)    ;Handle de la Fenêtre
          Debug "-------------------"
          
        Case #HCBT_SYSCOMMAND 
          ;Ici je ne traite pas 

      EndSelect
  EndSelect
  
  ProcedureReturn Resultat 
EndProcedure 


If OpenWindow(0,0,0,120,0,#PB_Window_SystemMenu|#PB_Window_TitleBar,"Pour quitter")
  
  SetWindowCallback(@ProcedureCallback()) 
  
  Hmodule = OpenLibrary(#Librairie, "c:\CBTHook.dll") 

  *Vue=CallFunction(#Librairie, "Initialiser_Hook", WindowID(0),Hmodule)

  If *Vue=0
    MessageRequester("Info", "Erreur")
  EndIf
  
   
  Repeat  
  Until WaitWindowEvent() = #PB_EventCloseWindow
  
  If CallFunction(#Librairie, "Fermeture_Hook")=0
    MessageRequester("Info", "Erreur")
  EndIf
  
EndIf
Dernière modification par nico le ven. 11/juin/2004 20:47, modifié 1 fois.
Ombres
Messages : 51
Inscription : sam. 24/janv./2004 12:46
Contact :

Message par Ombres »

Juste un truc pour la dll, d'apres la doc, un hook cbt ne doit pas
renvoyer "CallNextHookEx_(Hook,nCode,wParam,lParam)" quand
il a traité l'information mais 0 si tu veux autoriser l'operation, ou 1 pour l'empècher.
Donc en général on renvoi 0 :)

Un autre truc, tu fais
Hook = SetWindowsHookEx_(#WH_CBT,@CbtHook(),Hinst,0)
et
UnhookWindowsHookEx_(*VueDonnees\Hook)
mais jamais de *VueDonnees\Hook = Hook ?

Sinon mon code est quasiment comme le tiens...
sauf que le tiens marche :P
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Bien vu, j'ai rajouté pour l'oubli de la sauvegarde du Hook.

Effectivement, on utilise ProcedureReturn (0 ou 1) pour le traitement de l'information ce qui signifie que le message est clos. Donc si tu as plusieurs Hook, seul le premier traitera l'information et pas les autres, ce qui n'est pas bon (A moins de le Vouloir).

Maintenant si tu fais un Hook que pour ton programme (donc pas dans une Dll), dans ce cas oui, tu utilises ProcedureReturn!

:)
Répondre