Bonjour,
Je cherche a récuperer les coordonnées de la souris quand elle est hors de mon application (sur le bureau, par exemple)
Quelqu'un peut il m'aider ?
Merci d'avance
Bonjour,
Je cherche a récuperer les coordonnées de la souris quand elle est hors de mon application (sur le bureau, par exemple)
Quelqu'un peut il m'aider ?
Merci d'avance
Bonjour
Il suffit d'utiliser la fonction GetCursorPos
Ben ça, c'est normal. Tu ne peux réceptionner que les messages de ton application. Pour recevoir les autres, il te faut passer par un hook. Pas d'autre solution, sauf à utiliser un timer pour lire les coordonnées toutes les X millisecondes. C'est pas très "propre" comme solution, mais c'est bien plus simple que le Hook.
Pas besoin de hook, pas besoin de capturer la souris non plus. GetCursorPos suffit. Exemple :
Le problème dans une application fenêtrée est que si la boucle des messages est blocante, l'application restera pratiquement bloquée jusqu'à ce qu'à ce que le focus la revienne. En effet, les événements claviers et souris ne sont notifiées qu'à l'application active. Pour ne pas être bloqué quand l'application n'a pas le focus, il faut utiliser PeekMessage au lieu de GetMessage ou encore faire appel aux threads.
Code C : 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 #include <stdio.h> #include <conio.h> #include <windows.h> int main() { puts("Appuyez sur une touche pour terminer."); while (!_kbhit()) { POINT cur_pos; GetCursorPos(&cur_pos); printf("(%ld, %ld)\n", cur_pos.x, cur_pos.y); Sleep(1000); } return 0; }
Bonjour,
J'ai essayé de coder une boucle de message (PeekMessage) dans un Thread, mais visiblement je ne recois rien.
Pourtant chaque Thread gère bien une file de messages ?
Peut etre la boucle de messages principale de l'application est elle en cause ?
La foncion Thread :
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 DWORD WINAPI ThreadFunction( LPVOID lpParam ) { BOOL done = FALSE; int sinsize = sizeof(csin); MSG msg; POINT pt; while(done == FALSE) { // if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { switch(msg.message) { case WM_LBUTTONDOWN : MessageBox(NULL, "WM_LBUTTONDOWN", "Reception du message", MB_OK|MB_ICONINFORMATION); done = TRUE; break; case WM_MOUSEMOVE : MessageBox(NULL, "WM_MOUSEMOVE", "Reception du message", MB_OK|MB_ICONINFORMATION); break; default : TranslateMessage(&msg); DispatchMessage(&msg); break; } } // } ExitThread((DWORD)0); //return 0; }
Bien sûr, tu ne reçevras pas les messages, mais au moins ton application ne sera pas bloquée et tu pourras appeler GetCursorPos à tout moment. C'était bien ton but non ?
Si ton but est d'être notifié des messages souris même quand le curseur n'est pas dans ta fenêtre, alors là il faudra en effet faire appel à un hook. Voici un bon article sur le sujet : [Tutoriel] Les DLLs > Hooks.Envoyé par dede92
Oui, c'est exactement ce que je cherche à faire !
J'ai fait le test d'un hook sur WH_MOUSE mais ça ne fonctionne toujours pas hors de la zone client !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 hkprc = MouseProc; hhook=SetWindowsHookEx(WH_MOUSE, hkprc, (HINSTANCE) NULL, GetCurrentThreadId());L'"appel au hook est dans WndProc, la procedure principale
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) { MOUSEHOOKSTRUCT *ms; if (nCode < 0) return CallNextHookEx(hhook, nCode, wParam, lParam); // ms = (MOUSEHOOKSTRUCT *) lParam; Afficher_Mouse (&ms->pt); // return CallNextHookEx(hhook, nCode, wParam, lParam); }
C'est parce que tu ne hookes que le thread de ta fenêtre, alors que tu devrais hooker tous les threads du système. Je t'ai donné un lien et tu ne l'as même pas regardé. Je ne vois pas ce que je peux faire de plus.J'ai fait le test d'un hook sur WH_MOUSE mais ça ne fonctionne toujours pas hors de la zone client !
A noter qu'un hook de bas niveau (_LL), même global, n'a pas besoin d'être dans une DLL
Aurais-tu un lien dans msdn qui le précise ? Je n'ai jamais réussi à en trouver, alors je préfère ne jamais m'appuyer là-dessus.
Euh ... non désolé ce code ne vient d'aucun de mes articles. Si tu avais réellement lu mon article, tu aurais fait un hook global dans une DLL et tu n'aurais certainement pas utilisé un WH_MOUSE. Voici l'exemple de code de l'article :Envoyé par dede92
hookman.c : gestionnaire du hook
Code C : 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 #include <stdio.h> #include <windows.h> int main() { HMODULE hmodHook = LoadLibrary("hook.dll"); HHOOK hHook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)GetProcAddress(hmodHook, "CallWndProc"), hmodHook, 0); if (hHook) { printf("Appuyez sur ENTREE pour terminer.\n"); getchar(); UnhookWindowsHookEx(hHook); } FreeLibrary(hmodHook); return 0; }
hook.c : la DLL du hook
Dans ton cas tu veux surveiller les messages WM_MOUSExxx et compagine plutôt que les WM_CREATE et WM_DESTROY : que dois donc tu faire ?
Code C : 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 #include <stdio.h> #include <windows.h> struct { char FileName[MAX_PATH]; FILE * fOut; } MyApp; /* Représente le processus lié à la DLL. */ LRESULT CALLBACK CallWndProc(int code, WPARAM wParam, LPARAM lParam); BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { BOOL ret = TRUE; switch(fdwReason) { case DLL_PROCESS_ATTACH: strcpy(MyApp.FileName, "<unknown>"); GetModuleFileName(NULL, MyApp.FileName, sizeof(MyApp.FileName)); MyApp.fOut = fopen("c:\\hooklog.txt", "a"); if (MyApp.fOut == NULL) ret = FALSE; break; case DLL_PROCESS_DETACH: if (MyApp.fOut != NULL) fclose(MyApp.fOut); break; } return ret; } LRESULT CALLBACK CallWndProc(int code, WPARAM wParam, LPARAM lParam) { if (code == HC_ACTION) { PCWPSTRUCT lpcwps = (PCWPSTRUCT)lParam; switch(lpcwps->message) { case WM_CREATE: /* On va s'intéresser qu'aux fenêtres qui n'ont pas de parent. */ if (GetParent(lpcwps->hwnd) == NULL) { char lpBuffer[256]; fprintf(MyApp.fOut, "[WM_CREATE]\n"); fprintf(MyApp.fOut, "App=%s\n", MyApp.FileName); *lpBuffer = '\0'; GetClassName(lpcwps->hwnd, lpBuffer, sizeof(lpBuffer)); fprintf(MyApp.fOut, "Class=%s\n", lpBuffer); *lpBuffer = '\0'; GetWindowText(lpcwps->hwnd, lpBuffer, sizeof(lpBuffer)); fprintf(MyApp.fOut, "Name=%s\n", lpBuffer); fprintf(MyApp.fOut, "Handle=%#010x\n\n", (unsigned)lpcwps->hwnd); } break; case WM_DESTROY: if (GetParent(lpcwps->hwnd) == NULL) { fprintf(MyApp.fOut, "[WM_DESTROY]\n"); fprintf(MyApp.fOut, "Handle=%#010x\n\n", (unsigned)lpcwps->hwnd); } break; } } return CallNextHookEx(NULL, code, wParam, lParam); }
Non en effet et l'aide sur SetWindowsHookEx n'a pas beaucoup évolué depuis l'introduction des Low Level hooks.
Mais à partir du moment ou il y a un switch de processus à l'exécution et qu'on a passé un hModule et un pointeur correct sur la procédure, aucun soucis Ce n'est pas le hook qui charge la DLL et détermine le point d'entrée... Je peux même te dire que j'utilise ce principe dans l'une de mes applications depuis Windows 2000.
Il faudra que je revérifie, mais il me semble que ça fonctionne aussi avec une application 32bit dans un environnement 64bit. Ce qui serait une raison de plus pour se passer de DLL (Bien que Microsoft conseille maintenant de se passer de Low Level Hooks et de reporter cette gestion au niveau Raw Input)
Bref, fais un petit test et tu seras convaincu de la faisabilité
Personnellement, tant que Microsoft reste ferme sur le fait qu'un hook global doit être implémentée dans une DLL, je ne peux que recommander cette méthode et uniquement cette méthode. Windows n'est pas Open Source. On ne sait pas toujours les conséquences que peuvent engendrer les violations de règles.
Je n'ai jamais dit que je n'en étais pas convaincu ou que je n'avais jamais fait des test. Mes différentes expériences sur les hooks m'ont en effet fait remarquer à l'époque que certains hooks globaux n'avaient pas besoin d'être implémentées dans une DLL, et cela ne concerne pas que les low levl hooks. J'ai tout simplement dit que la doc officielle désapprouve cette pratique et qu'il vaut donc mieux ne pas en tenir compte.Bref, fais un petit test et tu seras convaincu de la faisabilité
J'ai finalement abouti à un résultat.
L'appel au Hook
Et la dll
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 hmodHook = LoadLibrary("dllmouse"); //TestProc(); hHook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)GetProcAddress(hmodHook, "MouseProc"), hmodHook, 0); if (!hHook) ErrorExit(TEXT("SetWindowsHookEx"));
Au départ cela ne fonctionnait pas à cause de la ligne 48 où j'avais codé
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 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include <windows.h> #include <stdio.h> #define WM_HOOK WM_USER+1 #define DllExport __declspec( dllexport) #define DllImport __declspec(dllimport) BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch(ul_reason_for_call) { case DLL_PROCESS_ATTACH: // MessageBox(NULL, "Chargement Dll", "DllMouse", MB_OK|MB_ICONINFORMATION); break; case DLL_PROCESS_DETACH: break; } return TRUE; } /////////////////////////////////////////////////////////////////////////////////// // Envoyer un message à la fenêtre destrinatrice s'il s'agit d'un message // // WM_MOUSEMOVE ou WM_NCMOUSEMOVE // // Récupération coordonnées de la souris // /////////////////////////////////////////////////////////////////////////////////// DllExport LRESULT MouseProc(int code, WPARAM wParam, LPARAM lParam) { PMOUSEHOOKSTRUCT lpms; HWND hWndDest; // hWndDest = FindWindow("CaptMouse", NULL); if (code == HC_ACTION) { lpms = (PMOUSEHOOKSTRUCT)lParam; switch(wParam) { case WM_MOUSEMOVE: case WM_NCMOUSEMOVE: SendMessage(hWndDest, WM_HOOK, (WPARAM)0, MAKELPARAM(lpms->pt.x, lpms->pt.y)); break; } } return CallNextHookEx(NULL, code, wParam, lParam); } DllExport LRESULT TestProc(void) { MessageBox(NULL, "TestProc", "DllMouse", MB_OK|MB_ICONINFORMATION); return 0; }
Merci encore.
Code : Sélectionner tout - Visualiser dans une fenêtre à part PostMessage (lpms->hwnd, WM_HOOK, (WPARAM)0, MAKELPARAM(lpms->pt.x, lpms->pt.y));
Tu as raison.Envoyé par Andnotor
Je n'ai plus la liste mais un hook clavier clavier par exemple, ça marche toujours sans DLL.Envoyé par Andnotor
Envoyé par dede92
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager