Répétition du clique gauche de la souris
Le
Tao
Bonsoir à tous.
En fouillant dans mon disque dur externe, j'ai retrouvé un projet que je
n'ai pas su finir (ce qui m'arrive fréquement à vrai dire). J'ai voulu m'y
remettre, en pensant que le temps écoulé m'aurait servi d'expérience. Mais
le soucis est que je n'y arrive toujours pas
Le projet est le suivant, je voudrais pouvoir intercépter le clique gauche
de la souris et le répéter un certain nombre de fois. J'ai tenté de créer un
dll de hook avec, pour un premier temps, la touche contrôle comme
déclencheur, mais je n'y suis pas arrivé. Pourriez-vous m'aider ? Ou me
proposer une autre méthode beaucoup plus simple ?
Voici le code de ma dll :
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "main.h"
__declspec(dllexport) int lancerHook();
__declspec(dllexport) int arreterHook();
LRESULT CALLBACK fonctionTraitementHookClavier(int nCode, WPARAM wParam,
LPARAM lParam);
HINSTANCE hinstanceDLL; // handle dll
HHOOK hookClavier; // Handle hook
int repetitionClique = 1;
__declspec(dllexport) int lancerHook()
{
hookClavier = SetWindowsHookEx( WH_KEYBOARD ,
fonctionTraitementHookClavier , hinstanceDLL , 0 );
if(hookClavier == NULL)
{
return 0;
}
return 1;
}
__declspec(dllexport) int arreterHook()
{
int test1 = UnhookWindowsHookEx(hookClavier); return (test1 !=
0)?1:0;
}
LRESULT CALLBACK fonctionTraitementHookClavier(int nCode, WPARAM wParam,
LPARAM lParam)
{
POINT pt;
int i = 0;
if (nCode == HC_ACTION && wParam == VK_CONTROL)
{
while(i < 5)
{
GetCursorPos(&pt);
mouse_event(MOUSEEVENTF_LEFTDOWN, pt.x, pt.y, 0, 0);
Sleep(15);
mouse_event(MOUSEEVENTF_LEFTUP, pt.x, pt.y, 0, 0);
Sleep(15);
i++;
}
}
return CallNextHookEx(hookClavier,nCode,wParam,lParam);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
{
hinstanceDLL = hinstDLL;
break;
}
case DLL_PROCESS_DETACH:
arreterHook();
break;
}
return TRUE;
}
Et le code du programme l'utilisant :
void FenPrincipale::onHook()
{
HINSTANCE hDll;
lancerHook test;
hDll = LoadLibraryA("hookRepetition.dll");
if(hDll != NULL)
{
QMessageBox::information(this, "Test", "Chargement Ok");
test = (lancerHook) GetProcAddress((HINSTANCE)hDll, "lancerHook");
test();
FreeLibrary(hDll);
}
}
(Peut être que le problème ne vient pas de la DLL mais j'en doute).
En espérant être aidé. Bonsoir.
En fouillant dans mon disque dur externe, j'ai retrouvé un projet que je
n'ai pas su finir (ce qui m'arrive fréquement à vrai dire). J'ai voulu m'y
remettre, en pensant que le temps écoulé m'aurait servi d'expérience. Mais
le soucis est que je n'y arrive toujours pas
Le projet est le suivant, je voudrais pouvoir intercépter le clique gauche
de la souris et le répéter un certain nombre de fois. J'ai tenté de créer un
dll de hook avec, pour un premier temps, la touche contrôle comme
déclencheur, mais je n'y suis pas arrivé. Pourriez-vous m'aider ? Ou me
proposer une autre méthode beaucoup plus simple ?
Voici le code de ma dll :
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "main.h"
__declspec(dllexport) int lancerHook();
__declspec(dllexport) int arreterHook();
LRESULT CALLBACK fonctionTraitementHookClavier(int nCode, WPARAM wParam,
LPARAM lParam);
HINSTANCE hinstanceDLL; // handle dll
HHOOK hookClavier; // Handle hook
int repetitionClique = 1;
__declspec(dllexport) int lancerHook()
{
hookClavier = SetWindowsHookEx( WH_KEYBOARD ,
fonctionTraitementHookClavier , hinstanceDLL , 0 );
if(hookClavier == NULL)
{
return 0;
}
return 1;
}
__declspec(dllexport) int arreterHook()
{
int test1 = UnhookWindowsHookEx(hookClavier); return (test1 !=
0)?1:0;
}
LRESULT CALLBACK fonctionTraitementHookClavier(int nCode, WPARAM wParam,
LPARAM lParam)
{
POINT pt;
int i = 0;
if (nCode == HC_ACTION && wParam == VK_CONTROL)
{
while(i < 5)
{
GetCursorPos(&pt);
mouse_event(MOUSEEVENTF_LEFTDOWN, pt.x, pt.y, 0, 0);
Sleep(15);
mouse_event(MOUSEEVENTF_LEFTUP, pt.x, pt.y, 0, 0);
Sleep(15);
i++;
}
}
return CallNextHookEx(hookClavier,nCode,wParam,lParam);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
{
hinstanceDLL = hinstDLL;
break;
}
case DLL_PROCESS_DETACH:
arreterHook();
break;
}
return TRUE;
}
Et le code du programme l'utilisant :
void FenPrincipale::onHook()
{
HINSTANCE hDll;
lancerHook test;
hDll = LoadLibraryA("hookRepetition.dll");
if(hDll != NULL)
{
QMessageBox::information(this, "Test", "Chargement Ok");
test = (lancerHook) GetProcAddress((HINSTANCE)hDll, "lancerHook");
test();
FreeLibrary(hDll);
}
}
(Peut être que le problème ne vient pas de la DLL mais j'en doute).
En espérant être aidé. Bonsoir.

Poser une question


Avec une DLL, il faut utiliser une "Shared Data Section"
C'est plus simple de faire sans DLL avec un Low Level Hook.
Pour reprendre ton exemple (avec Ctrl Gauche, en testant sur Paint Shop
Pro par exemple, il clique bien 5 fois au même endroit) =>
HHOOK hKeyboardHook;
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc,
hInst, 0);
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM
lParam)
{
DWORD dwKey = 0;
if (lParam)
{
KBDLLHOOKSTRUCT *pkbdll = (KBDLLHOOKSTRUCT*)lParam;
dwKey = pkbdll->vkCode;
if (dwKey == VK_LCONTROL)
{
POINT pt;
int i = 0;
while(i < 5)
{
GetCursorPos(&pt);
mouse_event(MOUSEEVENTF_LEFTDOWN, pt.x, pt.y, 0, 0);
Sleep(15);
mouse_event(MOUSEEVENTF_LEFTUP, pt.x, pt.y, 0, 0);
Sleep(15);
i++;
}
}
}
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
Merci de ta réponse claire et précise, le soucis maintenant est que je
n'arrive pas à la réutiliser... (Pas de commentaires).
En fait je bloque sur le paramètre hInst... Voici l'utilisation du code que
je fais dans un projet C++ classique :
#include <iostream>
#include <string>
#include
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM
lParam);
HHOOK hKeyboardHook;
int main(void)
{
std::cout << "Test Hook" << std::endl;
getchar();
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc,
hInst, 0);
return 0;
}
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM
lParam)
{
DWORD dwKey = 0;
if (lParam)
{
KBDLLHOOKSTRUCT *pkbdll = (KBDLLHOOKSTRUCT*)lParam;
dwKey = pkbdll->vkCode;
if (dwKey == VK_LCONTROL)
{
POINT pt;
int i = 0;
while(i < 5)
{
GetCursorPos(&pt);
mouse_event(MOUSEEVENTF_LEFTDOWN, pt.x, pt.y, 0, 0);
Sleep(15);
mouse_event(MOUSEEVENTF_LEFTUP, pt.x, pt.y, 0, 0);
Sleep(15);
i++;
}
}
}
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
Pourrais-tu m'aider ?
Il faut faire une appli Win32 GUI, pas Console, sinon il faut créer un
thread.
hInst est le hInstance de WinMain() (= GetModuleHandle(NULL))
Bonsoir à tous (encore). Je suis désolé d'avoir autant de mal mais j'ai
l'impression (ou plutôt la certitude) que le hook lancé s'arrête
quasi-aussitôt. Le problème est que je ne sais pas comment faire pour que le
hook fonctionne en continu et qu'à chaque touche appuyée, la fonction de
traitement la compare à la touche contrôle et que si cela correspond, alors
il simule le clic gauche de la souris.
Pourriez-vous m'aider à surmonter ce problème ?
Voici le code utilisé :
#include #include #include
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM
lParam);
HHOOK hKeyboardHook;
int WINAPI WinMain(HINSTANCE a, HINSTANCE b, LPSTR c, int d)
{
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc,
a, 0);
if(hKeyboardHook == NULL)
{
printf("Le hook n'a pas pu être lancénn");
getchar();
}
return 0;
}
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM
lParam)
{
DWORD dwKey = 0;
if (lParam)
{
KBDLLHOOKSTRUCT *pkbdll = (KBDLLHOOKSTRUCT*)lParam;
dwKey = pkbdll->vkCode;
if (dwKey == VK_LCONTROL)
{
POINT pt;
int i = 0;
while(i < 5)
{
GetCursorPos(&pt);
mouse_event(MOUSEEVENTF_LEFTDOWN, pt.x, pt.y, 0, 0);
Sleep(15);
mouse_event(MOUSEEVENTF_LEFTUP, pt.x, pt.y, 0, 0);
Sleep(15);
i++;
}
}
}
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
Ps : Merci de votre prochaine aide et veuillez m'excuser si je suis un peu
"lent à la détente" mais j'ai un peu de mal avec l'API Windows, bien qu'elle
soit très pratique.
Parce qu'il n'y a pas de Message Loop.
Il suffit de partir du Winzard Win32 de VC++ ou VS.NET.
Par ex, avec ajout touche F11 pour arrêter le Hook =>
#include #include
HINSTANCE hInst;
HHOOK hKeyboardHook;
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM
lParam);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc,
hInstance, 0);
Beep(200, 200);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM
lParam)
{
DWORD dwKey = 0;
if (lParam)
{
KBDLLHOOKSTRUCT *pkbdll = (KBDLLHOOKSTRUCT*)lParam;
dwKey = pkbdll->vkCode;
if (dwKey == VK_LCONTROL)
{
POINT pt;
int i = 0;
while(i < 5)
{
GetCursorPos(&pt);
mouse_event(MOUSEEVENTF_LEFTDOWN, pt.x, pt.y, 0, 0);
Sleep(15);
mouse_event(MOUSEEVENTF_LEFTUP, pt.x, pt.y, 0, 0);
Sleep(15);
i++;
}
}
if (dwKey == VK_F11)
{
Beep(500, 200);
UnhookWindowsHookEx(hKeyboardHook);
PostQuitMessage(0);
}
}
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}