Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

Problema de Ejecucion de Hook de teclado en DLL

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: Problema de Ejecucion de Hook de teclado en DLL Responder citando

estoy haciendo una aplicacion en la cual, me capture una combinacion de teclas determinada, aun cuando el programa este menimizado, al generase dicha combinacion, esta realize la operaciòn asignada a dicha combinacion.

Estoy probando con es programa, que transcribo integramente, pero me genera el
siguiente error en tiempo de ejecuciòn.

Cita:
Access violation at address 00000000. Read of address 00000000


El codigo es el siguiente:

Consta de una DLL y un a forma,
a continuacuion el codigo de la DLL

Código:

// Crear un proyecto DLL
// Guadardar como hooksClSo.cpp y el proyecto como hooksClSo
//---------------------------------------------------------------------------

#include <windows.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
void _export InitHook(HWND hDest);
void _export EndHook();
LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK KeybdProc(int nCode,WPARAM wParam,LPARAM lParam);

// fonction d'initialisation de la DLL

#pragma argsused
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 _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->KeybdHookHandle = 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 _export EndHook()
{
     // Supression des hooks
     UnhookWindowsHookEx(VueDonnees->MouseHookHandle);
     UnhookWindowsHookEx(VueDonnees->KeybdHookHandle);
}

LRESULT CALLBACK _export MouseProc(int nCode,WPARAM wParam,LPARAM lParam)
{
     // On joue un son à chaque fois que l'utilisateur enfonce le bouton gauche
     if (wParam == WM_LBUTTONDOWN)
         MessageBeep(MB_OK);
    return CallNextHookEx(VueDonnees->MouseHookHandle,nCode,wParam,lParam);
}

#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 (wParam == VK_RETURN)
          PostMessage(VueDonnees->hDestWindow, WMAP_KEYBDHOOKMSG, 0, 0);

     return CallNextHookEx(VueDonnees->KeybdHookHandle,nCode,wParam,lParam);
}


Enseguida viene el codigo de la aplicacion que hace uso de la DLL
---- Crear un nuevo proyecto de applicacion
Se crea una forma
se agrega un chechbox, con caption "Hooks [ON/OFF]"
y un etiqueta LAbel1 con caption "Pressions de ENTREE:"
Código:

// Archivo de cabecera appli.h
//---------------------------------------------------------------------------

#ifndef appliH
#define appliH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>

typedef void (*TInitFunc)(HWND);
typedef void (*TEndFunc)();
         
#define WMAP_KEYBDHOOKMSG WM_APP + 1

//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:   // IDE-managed Components
        TCheckBox *CheckBox1;
        TLabel *Label1;
        void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
        void __fastcall CheckBox1Click(TObject *Sender);
private:   // User declarations
          TInitFunc InitHooks; // fonction d'initialisation des hooks
          TEndFunc EndHooks; // fonction de suppression des hooks
          HINSTANCE hinstDLL; // instance de la DLL
          bool bHook; // Les hooks ont-ils été initialisés ?
          int nbEntree; // compteur de pressions pour le gestionnaire de messages
          public: // Déclarations utilisateur
          void __fastcall PressionEntree(TWMNoParams &p);
        __fastcall TForm1(TComponent* Owner);
        protected: // déclaration du gestionaire de messages
          BEGIN_MESSAGE_MAP
               VCL_MESSAGE_HANDLER(WMAP_KEYBDHOOKMSG, TWMNoParams, PressionEntree)
          END_MESSAGE_MAP(TForm)


};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif


Ahora el codigo de appli.cpp

Código:

//-----appli.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "appli.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
    bHook = false; // Les hooks ne sont pas initialisés
     hinstDLL = LoadLibrary("hooksClSo.dll"); // Chargement de la librairie
     if (!hinstDLL) // Erreur lors du chargement de la librairie ?
          Application->MessageBox("Impossible de charger la librairie.","gloups",MB_OK);
     else
    {
          // On récupère les adresses des fonctions
          InitHooks = (TInitFunc)GetProcAddress(hinstDLL, "_InitHook");
          EndHooks = (TEndFunc)GetProcAddress(hinstDLL, "_EndHook");
     }

}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
     if (bHook) // Si les hooks sont actifs, on les supprime avant de quitter
          EndHooks();
         
     Action = caFree;

}
//---------------------------------------------------------------------------
void __fastcall TForm1::CheckBox1Click(TObject *Sender)
{
   if (!hinstDLL) // La librairie n'est pas chargée, inutile de continuer
          Close();
     else if (CheckBox1->Checked) // Activer les hooks
     {
          nbEntree = 0; // On réinitialise le compteur     
          InitHooks(Form1->Handle); // On initialise les hooks    <-- aqui
                                                        // se genera el error
     }
     else // Désactiver les hooks
          EndHooks(); // On supprime les hooks

}
//---------------------------------------------------------------------------
void __fastcall TForm1::PressionEntree(TWMNoParams &p)
{
     nbEntree++; // On a reçu un message du hook : on incrémente et on affiche le compteur
     Label1->Caption = AnsiString("Pressions de ENTREE : ") + nbEntree;
}




Dicho programa lleva el conteo de pulsaciones de la tecla ENTER.
Este programa lo tome de la pagina francesa.
http://tcharles.developpez.com/simul/

Alguna alguna sugerencia.
Lo que deseo es asignar una combinacion de Teclas. por Ejemplo
Ctrl+Alt+Z , al pulsarse esta combinacion de teclas, Visualizar
un mensaje, o tal vez agregar o quitar un elemento de una lista,
o si estoy reproduciendo un archivo de audio, Tocarlo, o hacer pausa

Gracias.
Miguel Angel Verastegui Diaz.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Solucion. Responder citando

La solucion está en Tips & Tricks

https://cppbuilder.es/viewtopic.php?t=9761
_________________
Miguel Angel Verastegui Diaz
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.