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

C++Builder Discussion :

Problème de Hook souris, application bloquée


Sujet :

C++Builder

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2009
    Messages : 39
    Par défaut Problème de Hook souris, application bloquée
    Bonjour à tous,

    Dans le cadre de mon application, j'utilise un hook souris afin de détecter une activité (ou plutôt l'inactivité) du système. Le problème est, qu'une fois l'application lancée, la souris ne répond plus et je suis obligé de redémarrer le système.

    C'est le premier hook que je code, je suppose qu'une fois le message intercepté par le hook, je ne le renvoie pas correctement pour qu'il soit traité normalement.

    Voici le code de ma DLL inspirée par quelques bouts de codes trouvés sur le net. J'ai ajouté un hook clavier juste pour le test.

    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
     
    #include <windows.h>
    #include <VCL.h>
    // Définition de la structure de la zone mémoire partagée
     
    typedef struct _TDonnees
    {
         HHOOK MouseHookHandle; // Handle du hook de la souris 
         HHOOK KeybdHookHandle; // Handle du hook du clavier
         HWND hDestWindow; // Handle de la fenêtre à laquelle le hook du clavier doit les données
         // Mettez ici toutes les données que vous voulez partager
    } TDonnees;
     
    // Déclaration des variables globales de la DLL
    HANDLE MemPartagee; // Handle de la zone de mémoire partagée
    TDonnees * VueDonnees; // Pointeur vers la zone de mémoire
    HINSTANCE HInst; // Handle d'intance de la DLL
     
    // Déclaration des fonctions de la DLL
    extern "C" __stdcall void _export InitHook(HWND hDest);
    extern "C" __stdcall void _export EndHook();
     
    LRESULT CALLBACK _export MouseProc(int nCode,WPARAM wParam,LPARAM lParam);
    LRESULT CALLBACK _export KeybdProc(int nCode,WPARAM wParam,LPARAM lParam);
     
    // fonction d'initialisation de la DLL
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
         HInst = hinst;
         switch (reason)
         {
              case DLL_PROCESS_ATTACH : // à la création de l'instance de la DLL
                   // Attachement d'une zone de mémoire partagée (notez le cast)
                   MemPartagee = CreateFileMapping((HANDLE)0xFFFFFFFF, // On map un espace mémoire
                                            NULL, // Pas d'informations de sécurité
                                            PAGE_READWRITE, // Partage en lecture/écriture
                                            0, // Taille de la zone réservée sur 64 bits (32 bits de poid fort)
                                            sizeof(TDonnees), // 32 bits de poids faible
                                            "Tutoriel Hooks par gRRosminet"); // Nom de la zone réservée
     
                   // Création d'une vue pour pouvoir accéder à la zone de mémoire partagée (notez le cast)
                   VueDonnees = (TDonnees *)(MapViewOfFile((HANDLE)MemPartagee, // Zone sur laquelle créer la vue
                                            FILE_MAP_WRITE, // Mode d'accès en lecture/écriture
                                            0, 0, // Offset de début de la vue sur 64 bits
                                            0)); // Taille de la vue (0 = tout)
                                            break;
     
              case DLL_PROCESS_DETACH : // au détachement de la DLL
                   // Destruction de la vue sur la zone de mémoire partagée
                   UnmapViewOfFile((LPVOID)VueDonnees);
                   // Détachement de la zone de mémoire partagée
                   CloseHandle(MemPartagee);
                   break;
     
              default :
                   // DLL_THREAD_ATTACH, DLL_THREAD_DETACH
                   break;
         }
         return 1;
    }
     
    void __stdcall _export InitHook(HWND hDest) // _export est spécifique à BCB
    {
    	 // Installation du hook sur la souris
    	 VueDonnees->MouseHookHandle = SetWindowsHookEx(WH_MOUSE, // Créer un hook sur la souris
            (HOOKPROC)MouseProc, // Utiliser la fonction MouseProc
             HInst, // Dans la DLL d'instance HInst
    	 0); // Pour tous les threads
     
             // Installation du hook pour le clavier
    	 VueDonnees->MouseHookHandle = SetWindowsHookEx(WH_KEYBOARD, // Créer un hook sur le clavier
    	(HOOKPROC)KeybdProc, // Utiliser la fonction KeybdProc
    	 HInst, // Dans la DLL d'instance HInst
    	 0); // Pour tous les threads
     
         // Partage de la fenêtre destinatrice des données du clavier
         VueDonnees->hDestWindow = hDest;
    }
     
    void __stdcall _export EndHook()
    {
         // Supression des hooks
         UnhookWindowsHookEx(VueDonnees->MouseHookHandle);
         UnhookWindowsHookEx(VueDonnees->KeybdHookHandle);
    }
     
    #define WMAP_MOUSEHOOKMSG WM_APP + 2
     
    LRESULT CALLBACK _export MouseProc(int nCode,WPARAM wParam,LPARAM lParam)
    {
    	 // On envoie un message WMAP_MOUSEHOOKMSG à chaque fois que
    	 // l'utilisateur presse sur la souris (bouton gauche)
    	 if(nCode < 0) return CallNextHookEx(VueDonnees->MouseHookHandle,nCode,wParam,lParam);
    	 else
    	 {
    		if (wParam == WM_LBUTTONDOWN)
    		{
    			PostMessage(VueDonnees->hDestWindow, WMAP_MOUSEHOOKMSG, 0, 0);
    		}
    	 }
    }
     
    #define WMAP_KEYBDHOOKMSG WM_APP + 1
     
    LRESULT CALLBACK _export KeybdProc(int nCode,WPARAM wParam,LPARAM lParam)
    {
    	 // On envoie un message WMAP_KEYBDHOOKMSG à chaque fois que
    	 // l'utilisateur presse la touche ENTREE
    	 if(nCode < 0) return CallNextHookEx(VueDonnees->KeybdHookHandle,nCode,wParam,lParam);
    	 else
    	 {
    		if (wParam == VK_RETURN)
    		{
    			PostMessage(VueDonnees->hDestWindow, WMAP_KEYBDHOOKMSG, 0, 0);
    		}
    	 }
    }
    Voici le fichier d'entête de mon code source:
    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
     
    #ifndef MainFormH
    #define MainFormH
    //---------------------------------------------------------------------------
    #include "Windows.h"
    #include <string>
    #include <fstream>
    #include <iostream>
    #include <dbt.h> // used for the windows message function
     
    //--------------------------------------------------------------------------
     
    typedef void (__stdcall *TInitFunc)(HWND);  // déclarations des fonctions pour les hooks
    typedef void (__stdcall *TEndFunc)();
     
    #define WMAP_MOUSEHOOKMSG WM_APP + 2 //used for the hook
    #define WMAP_KEYBDHOOKMSG WM_APP + 1  //used for the hook
     
    class TForm_Main : public TForm
    {
     
    private:	// User declarations
     
    // Variables
    	bool bHook; // Les hooks ont-ils été initialisés ?
    	int nbEntree; // compteur de pressions pour le gestionnaire de messages
            int nbSouris  // compteur de clics pour le gestionnaire de messages
            HINSTANCE hinstDLL; // instance de la DLL
     
    public:
    // Functions
     
    	__fastcall TForm_Main(TComponent* Owner);
    	__fastcall ~TForm_Main();
     
            TInitFunc InitHooks; // fonction d'initialisation des hooks
    	TEndFunc EndHooks; // fonction de suppression des hooks
     
    	// fonction appelée par le message WMAP_MOUSEHOOKMSG (clic gauche)
            void __fastcall   TForm_Main::MouseDetection(TWMNoParams &p);
            // fonction appelée par le message WMAP_KEYBDHOOKMSG (pression touche "entrée"
    	void __fastcall TForm_Main::PressionEntree(TWMNoParams &p);
            BEGIN_MESSAGE_MAP
    VCL_MESSAGE_HANDLER(WMAP_KEYBDHOOKMSG, TWMNoParams, PressionEntree)
    VCL_MESSAGE_HANDLER(WMAP_MOUSEHOOKMSG, TWMNoParams, MouseDetection)
    	END_MESSAGE_MAP(TForm)
     
    //  Variables
     
    //  Functions
     
    };
     
    //---------------------------------------------------------------------------
    extern PACKAGE TForm_Main *Form_Main;
    //---------------------------------------------------------------------------
    #endif
    et finalement le fichier source où se trouvent les fonctions appelées par les deux hooks (clavier et souris).
    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
     
    #include <vcl.h>
    #pragma hdrstop
    #include "MainForm.h"
    #include <mmsystem.h>
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
     
    TForm_Main *Form_Main;
     
    void __fastcall TForm_Main::PressionEntree(TWMNoParams &p)
    {
    	 nbEntree++; // On a reçu un message du hook : on incrémente et on affiche le compteur
    	 LHookKeyboard->Caption = "Pressions de ENTREE : " + IntToStr(nbEntree);
    }
    void   __fastcall   TForm_Main::MouseDetection(TWMNoParams &p)
    {
    	nbSouris++; // On a reçu un message du hook : on incrémente et on affiche le compteur
    	LHookSouris->Caption = "Pressions de Souris: " + IntToStr(nbSouris);
    }
    //---------------------------------------------------------------------------
    __fastcall TForm_Main::TForm_Main(TComponent* Owner)
    	: TForm(Owner)
    {
    	// Hooks souris et clavier
    	hinstDLL = LoadLibrary("HookDLL.dll"); // Chargement de la librairie
    	if (!hinstDLL) // Erreur lors du chargement de la librairie ?
    	{
    		  ErrorManagement("Erreur dans le chargement de la DLL");
    		  Application->Terminate();
    	}
    	else
    	{
    		  // On récupère les adresses des fonctions
              InitHooks = (TInitFunc)GetProcAddress(hinstDLL, "InitHook");
    		  EndHooks = (TEndFunc)GetProcAddress(hinstDLL, "EndHook");
    	}
     
    	InitHooks(Form_Main->Handle); // On initialise les hooks
    	nbEntree = 0;
            nbSouris = 0;
    }
    __fastcall TForm_Main::~TForm_Main()
    {
    	// end hooks
    	EndHooks();
    }
    La DLL est bien chargée, les fonctions MouseDetection et PressionEntree sont bien appelées, mais la souris ne marche plus du tout, comme si le hook ne renvoyait pas le message du clic. La fonction PressioEntree fonctionne bien mais ne renvoie pas non plus l'information (le programme détecte une pression, mais une entrée dans un objet TEdit ne fait pas de saut à la ligne par exemple)

    Je patauge un peu dans le yahourt ces derniers jours, j'espère que l'un de vous pourra me donner quelques conseils ou même me trouver une solution!

    Merci d'avance et bonne journée (ensoleillée je l'espère!)

    Frédéric

  2. #2
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2005
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 401
    Par défaut
    Hello,

    Il me semble qu'il faut appeler systématiquement CallNextHookEx:
    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
    #define WMAP_MOUSEHOOKMSG WM_APP + 2
    LRESULT CALLBACK _export MouseProc(int nCode,WPARAM wParam,LPARAM lParam)
    {
      if(nCode >= 0) 
        if (wParam == WM_LBUTTONDOWN)
          PostMessage(VueDonnees->hDestWindow, WMAP_MOUSEHOOKMSG, 0, 0);
     
      return CallNextHookEx(VueDonnees->MouseHookHandle,nCode,wParam,lParam);
    }
     
    #define WMAP_KEYBDHOOKMSG WM_APP + 1
    LRESULT CALLBACK _export KeybdProc(int nCode,WPARAM wParam,LPARAM lParam)
    {
      if(nCode >= 0) 
        if (wParam == VK_RETURN)
          PostMessage(VueDonnees->hDestWindow, WMAP_KEYBDHOOKMSG, 0, 0);
     
      return CallNextHookEx(VueDonnees->KeybdHookHandle,nCode,wParam,lParam);
    }
    cf MSDN:
    If code is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_KEYBOARD hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2009
    Messages : 39
    Par défaut
    Salut Totoche76,

    Merci pour ta remarque, effectivement, grâce à ça, les messages sont bien transmis... C'était vraiment con et j'y ai passé 2 jours

    Ouf, un problème de résolu, suivant!

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 03/03/2013, 13h21
  2. Problème avec hook souris
    Par Pouknouki dans le forum VB.NET
    Réponses: 0
    Dernier message: 27/02/2013, 05h54
  3. Problème d'installation d'application ".msi"
    Par maddog2032 dans le forum Windows Serveur
    Réponses: 4
    Dernier message: 16/09/2005, 11h31
  4. Probleme de Hook souris
    Par mandagor dans le forum MFC
    Réponses: 17
    Dernier message: 07/07/2005, 17h12
  5. Réponses: 1
    Dernier message: 03/05/2005, 09h12

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