SoloCodigo

Programación General => C/C++ => Mensaje iniciado por: tonilope en Lunes 23 de Octubre de 2006, 01:23

Título: Problemilla Con Keyboard Hook
Publicado por: tonilope en Lunes 23 de Octubre de 2006, 01:23
Hola. He escrito este pequeño programa para poder controlar el WinAmp mientras estoy en otras aplicaciones. Funciona de lujo, salvo cuando estoy en el Mozilla. El problema es que cada pulsación de teclado el Mozilla lo intepreta como dos pulsaciones seguidas, lo que hace que mi programa funcione mal (salta las canciones de dos en dos, por ejemplo). Como sólo me pasa con esta aplicación, imagino que no será culpa mia, pero me gustaría corregirlo de alguna manera (leer el título de la ventana activa y contrastarlo con una lista negra NO me sirve ya que no conozco todas las aplicaciones afectadas con ese "fallo").

Os pongo el código fuente del programa (YA ARREGLADO):

lib_hook.c

Código: Text
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <windows.h>
  5.  
  6. #include "dll.h"
  7.  
  8. typedef union {
  9.    struct {
  10.       unsigned int repeticion:16;
  11.       unsigned int scan:8;
  12.       unsigned int extendida:1;
  13.       unsigned int reservado:4;
  14.       unsigned int contexto:1;
  15.       unsigned int previo:1;
  16.       unsigned int transicion:1;
  17.    };
  18.    unsigned int lParam;
  19. }keyData;
  20.  
  21. static HHOOK hookteclado;
  22. static HINSTANCE hInstance;
  23.  
  24.  
  25. DLLIMPORT LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
  26. {
  27.  
  28. int tecla=(int)wParam;
  29.  
  30. keyData info_tecla;
  31.  
  32. info_tecla.lParam=lParam;
  33.  
  34. if(code>=0 && code!=HC_NOREMOVE)
  35. {
  36.  
  37. //CTRL + ALT + 'hot key'
  38. if(info_tecla.transicion==0 && info_tecla.contexto==1 && HIBYTE(GetKeyState(VK_CONTROL)))
  39.     SendMessage(FindWindowEx(NULL, NULL, "Winamp v1.x", NULL), WM_KEYDOWN, tecla, 0);
  40.  
  41.  
  42. }
  43.  
  44. return CallNextHookEx(NULL, code, wParam, lParam);
  45.  
  46. }
  47.  
  48.  
  49. DLLIMPORT void activa_hook()
  50. {
  51. hookteclado = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,hInstance,0);
  52. }
  53.  
  54. DLLIMPORT void desactiva_hook()
  55. {
  56. UnhookWindowsHookEx(hookteclado);
  57. }
  58.  
  59.  
  60. BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
  61. {
  62.  
  63.     switch(reason)
  64.     {
  65.      
  66.       case DLL_PROCESS_ATTACH:
  67.            hInstance=hInst;
  68.            break;
  69.  
  70.       case DLL_PROCESS_DETACH:
  71.            break;
  72.  
  73.       case DLL_THREAD_ATTACH:
  74.            hInstance=hInst;
  75.            break;
  76.  
  77.       case DLL_THREAD_DETACH:
  78.            break;
  79.            
  80.     }
  81.  
  82.     return TRUE;
  83. }
  84.  
  85.  
  86.  
  87.  

dll.h
Código: Text
  1.  
  2. #ifndef _DLL_H_
  3. #define _DLL_H_
  4.  
  5. #if BUILDING_DLL
  6. # define DLLIMPORT __declspec (dllexport)
  7. #else /* Not BUILDING_DLL */
  8. # define DLLIMPORT __declspec (dllimport)
  9. #endif /* Not BUILDING_DLL */
  10. DLLIMPORT void desactiva_hook(void);
  11. DLLIMPORT void activa_hook(void);
  12.  
  13. #endif
  14.  
  15.  

controlador_winamp.c
Código: Text
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <windows.h>
  5.  
  6. int main()
  7. {
  8. HINSTANCE hinstDLL;
  9. FARPROC activa_hook;
  10. FARPROC desactiva_hook;
  11.  
  12.     printf("\n\tWinAmp [Background] Controlator 0.1 (by tonilope)\n\n");
  13.     printf("\n\nLista de Hot-Keys mas utilizadas: (CTRL + ALT + HOTKEY)\n");
  14.   printf("\n\n[Z]: Previa");
  15.   printf("\n\n[X]: Play");
  16.   printf("\n\n[C]: Pausa/Reanudar");
  17.   printf("\n\n[V]: Stop");
  18.   printf("\n\n[B]: Siguiente");
  19.   printf("\n\n[2](Bloq. num): Bajar volumen");
  20.   printf("\n\n[8](Bloq. Num): Subir volumen");
  21.  
  22. if((hinstDLL=LoadLibrary("lib_hook.dll"))!=NULL)
  23. {
  24.  
  25. activa_hook=(FARPROC)GetProcAddress(hinstDLL, "activa_hook");
  26. desactiva_hook=(FARPROC)GetProcAddress(hinstDLL, "desactiva_hook");
  27.  
  28. if(activa_hook!=NULL && desactiva_hook!=NULL)
  29. {
  30.  
  31. printf("\n\n\tActivando hook del teclado...");
  32.  
  33. activa_hook();
  34.  
  35. printf("\tOK");
  36.  
  37. printf("\n\n\t\t(Pulsa 'D' para desactivarlo)");
  38.  
  39. while(toupper(getch())!='D');
  40.  
  41. printf("\n\n\tDesactivando hook del teclado...");
  42.  
  43. desactiva_hook();
  44.  
  45. printf("\tOK");
  46.  
  47. FreeLibrary(hinstDLL);
  48. }
  49.  
  50. }
  51. else
  52. printf("\n\n\tERROR: NO se encuentra lib_hook.dll");
  53.  
  54. printf("\n\n\t\tPulsa una tecla para cerrar...");
  55.  
  56. getch();
  57.  
  58. return 0;
  59. }
  60.  
  61.  

Salu2 ;)
Título: Re: Problemilla Con Keyboard Hook
Publicado por: Eternal Idol en Lunes 23 de Octubre de 2006, 10:13
Primero la parte mala, tuve que hacer esto:

Código: Text
  1.  
  2. //#include "dll.h"
  3.  
  4. #define DLLIMPORT __declspec(dllexport)
  5.  
  6.  

Y me costo entender un poco como funcionaba la cosa ...

Segundo la parte buena, en cuanto lo tuve funcionando y mire la documentacion de KeyboardProc acerte el problema en el primer intento.

Mira atentamente el parametro code, estas tomando en cuenta solo una parte  ;)
Título: Re: Problemilla Con Keyboard Hook
Publicado por: tonilope en Lunes 23 de Octubre de 2006, 11:16
:unsure:  ... HC_NOREMOVE  :lol:  :lol: ¡Pues claro! Qué despiste más tonto... GRACIAS.

Salu2 ;)
Título: Re: Problemilla Con Keyboard Hook
Publicado por: Eternal Idol en Lunes 23 de Octubre de 2006, 11:27
Cita de: "tonilope"
:unsure:  ... HC_NOREMOVE  :lol:  :lol: ¡Pues claro! Qué despiste más tonto... GRACIAS.

Salu2 ;)
Efestivamente HC_NOREMOVE era lo que faltaba :devil: De nadas  :smartass: