dreamermx Lt JG

Registrado: 14 Oct 2004Mensajes: 57Ubicación: Acapulco Guerrero Mexico
|
Publicado: Mar 22 Feb, 2005 9:42 pm Asunto: Problema de Ejecucion de Hook de teclado en DLL |
|
|
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. |
|