Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > API de Windows
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 06-09-2007
PedroElFlaky PedroElFlaky is offline
Miembro
 
Registrado: sep 2007
Posts: 11
Poder: 0
PedroElFlaky Va por buen camino
El Hook no funciona desde que actúo sobre otras aplicaciones

Hola a todos, es la primera vez que me registro pero siempre leo el foro y me ha ayudado mucho, lo que me sucede es lo siguiente:

Tengo un hook global de teclado que escribe las teclas pulsadas en un memo (como los que he visto en este foro). Lo que sucede es que al ejecutar mi aplicación, funciona normalmente, si paso a otra ventana activa en la que no se puede usar el teclado y pulso una tecla, mi programa sigue funcionando normalmente, pero en cuanto escribo algo en otra aplicación de las que si reciben eventos del teclado (es decir un notepad por ejemplo, en el cual se puede escribir), entonces a partir de ese momento el sistema deja de notificar a mi dll de la pulsación de las teclas.

Espero que alguien pueda orientarme para saber qué clase de cosa es lo que estoy haciendo mal.

Saludos
Responder Con Cita
  #2  
Antiguo 06-09-2007
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Cita:
Espero que alguien pueda orientarme para saber qué clase de cosa es lo que estoy haciendo mal.
Eso va a resultar complicado, puesto que no sabemos cómo lo estás haciendo. El asunto es que si no recuerdo mal lo que quieres conseguir es posible (de ahí los famosos "Keyloggers"), pero, sin saber cómo tratas de hacerlo tú (sin conocer el código fuente que empleas) es complicado decirte qué estás haciendo mal, si es que estás haciendo algo mal, vaya.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #3  
Antiguo 07-09-2007
PedroElFlaky PedroElFlaky is offline
Miembro
 
Registrado: sep 2007
Posts: 11
Poder: 0
PedroElFlaky Va por buen camino
Tengo una aplicación y una dll.
Al crear la aplicación cargo la dll, le envío el handle de la aplicación con pasar_handle_a_dll () y llamo a HookOn() y al cerrarla, llamo a HookOff() y libero la dll. En la aplicación, recibo mensajes de la dll con las teclas pulsadas y las paso al memo. Puse una variable global en la dll en la que ponía la última tecla detectada, para así desde la aplicación acceder a esta variable y así pude comprobar, que cuando mi programa deja de detectar teclas, no es porque no reciba mensajes de la dll sino porque en la dll se dejan de detectar las teclas. Así que el problema debe de estar en la dll.

Lo que tengo en la dll es:

Código Delphi [-]
library ProjectDll;   uses Windows; uses Messages;  const  MSG_TECLA_DOWNUP = WM_USER + $1;  var  MiHook     : HHook;  ApliHandle     : THandle;  ApliHandle^     : THandle;   function CallBackDeMiHook ( Code    : Integer;                           wParam  : WPARAM;                           lParam  : LPARAM                           )       : LRESULT; stdcall; begin  {Si una tecla fue pulsada o liberada}    if code=HC_ACTION then     PostMessage(ApliHandle, MSG_TECLA_DOWNUP, wParam, lParam);      Result := CallNextHookEx(MiHook, Code, wParam, lParam) end;   procedure HookOn; stdcall; {Procedure que instala el hook}  begin   MiHook:=SetWindowsHookEx(WH_KEYBOARD, @ CallBackDeMiHook,         HInstance, 0); end;   procedure HookOff;  stdcall; begin {procedure para desinstalar el hook}    UnhookWindowsHookEx(MiHook); end; procedure pasar_handle_a_dll (phandle : THandle^);  stdcall; begin        pApliHandle = phandle;        ApliHandle = *pApliHandle;     end;  exports{Exportamos los procedures}  HookOn,  HookOff,  pasar_handle_a_dll;
Bueno, pues eso el lo tengo, Saludos
Responder Con Cita
  #4  
Antiguo 07-09-2007
PedroElFlaky PedroElFlaky is offline
Miembro
 
Registrado: sep 2007
Posts: 11
Poder: 0
PedroElFlaky Va por buen camino
Tengo una aplicación y una dll.
Al crear la aplicación cargo la dll, le envío el handle de la aplicación con pasar_handle_a_dll () y llamo a HookOn() y al cerrarla, llamo a HookOff() y libero la dll. En la aplicación, recibo mensajes de la dll con las teclas pulsadas y las paso al memo. Puse una variable global en la dll en la que ponía la última tecla detectada, para así desde la aplicación acceder a esta variable y así pude comprobar, que cuando mi programa deja de detectar teclas, no es porque no reciba mensajes de la dll sino porque en la dll se dejan de detectar las teclas. Así que el problema debe de estar en la dll.

Lo que tengo en la dll es:

Código Delphi [-]
library ProjectDll;
 
 
uses Windows;
uses Messages;
 
const
MSG_TECLA_DOWNUP = WM_USER + $1;
 
var
MiHook : HHook;
ApliHandle : THandle;
ApliHandle^ : THandle;
 
 
function CallBackDeMiHook ( Code : Integer;
wParam : WPARAM;
lParam : LPARAM
) : LRESULT; stdcall;
begin
{Si una tecla fue pulsada o liberada} 
if code=HC_ACTION then 
PostMessage(ApliHandle, MSG_TECLA_DOWNUP, wParam, lParam); 
 
Result := CallNextHookEx(MiHook, Code, wParam, lParam)
end;
 
 
procedure HookOn; stdcall;
{Procedure que instala el hook} 
begin
MiHook:=SetWindowsHookEx(WH_KEYBOARD, @ CallBackDeMiHook, HInstance, 0);
end;
 
 
procedure HookOff; stdcall;
begin
{procedure para desinstalar el hook} 
UnhookWindowsHookEx(MiHook);
end;
 
 
procedure pasar_handle_a_dll (phandle : THandle^); stdcall;
begin
pApliHandle = phandle;
ApliHandle = *pApliHandle; 
end;
 
 
exports
{Exportamos los procedures}
HookOn,
HookOff,
pasar_handle_a_dll;

Bueno, pues eso el lo tengo,

Saludos

Última edición por dec fecha: 07-09-2007 a las 09:12:50.
Responder Con Cita
  #5  
Antiguo 07-09-2007
PedroElFlaky PedroElFlaky is offline
Miembro
 
Registrado: sep 2007
Posts: 11
Poder: 0
PedroElFlaky Va por buen camino
He intentado poner mi post de las 2 formas y no sé cuál es peor, no sé como hacer para que el código no salga en una sola línea.
Responder Con Cita
  #6  
Antiguo 07-09-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Hola Pedro,

el problema es el siguiente. Cada vez que te cambias de apliacion, windows inyecta tu dll en el nuevo proceso, despues de la inyeccion las variables de la dll no contienen lo mismo que en la dll que esta cargada en tu proceso. Es decir, cada proceso va a tener su propia instancia de la dll.

Con el procedure pasar_handle_a_dll solo le estas dando el valor correcto a la variable ApliHandle que pertenece a la instancia de la dll que tiene cargada tu proceso. Para los demas procesos esa variable sigue sin inicializar.

Una vez localizado el problema tenemos dos prosibles soluciones. Las mas sencilla, si solo quieres capturar las pulsaciones de teclado, es utilizar un hook del tipo WH_KEYBOARD_LL en vez WH_KEYBOARD, estos no necesitan estar implementados en una dll y es el propio windows el que se encarga de hacer los cambios de contexto. La otra solucion es mapear las variables en la memoria global, de forma que puedan ser leidas desde cualquier proceso.

Ejemplo de la primera solución:
http://romansg.net/index.php?pg=hooks

La segunda solución no te la aconsejo a menos que necesites inyectarte en otro proceso por algún motivo en especial
Responder Con Cita
  #7  
Antiguo 09-09-2007
PedroElFlaky PedroElFlaky is offline
Miembro
 
Registrado: sep 2007
Posts: 11
Poder: 0
PedroElFlaky Va por buen camino
Hola de nuevo,

lo primero aclarar que si me gustaría inyectarme en todos los procesos y capturar las teclas de todos lo procesos, y tal vez más adelante, cuando tenga todo esto claro y funcione, probar con otros tipos de hooks

he quitado lo de pasar_handle_a_dll() y en lugar de ello, es la propia dll la que obtiene el handle de la ventana de mi aplicación con FindWindow() cada vez que se llama a CallBackDeMiHook(), es decir que donde antes tenía

PostMessage(ApliHandle, MSG_TECLA_DOWNUP, wParam, lParam);

ahora tengo

WindowApliHandle = FindWindow(0, "ApliHook");
PostMessage(WindowApliHandle, MSG_TECLA_DOWNUP, wParam, lParam);

Aun así mi programa se sigue comportando igual que antes, es decir que no solo no detecta las pulsaciones en las otras aplicaciones, sino que después de haber usado el teclado en las otras ya no detecta las pulsaciones en la mía.

Entonces tengo las siguientes dudas:
-si las variables globales son una copia diferente para cada aplicación que llama a mi dll, no estaría también la variable "MiHook" sin inicializar?
-al pasar de una aplicación a otra, las variables globales de la dll para mi aplicación, se resetean o cuando vuelva a mi aplicación conservarán su valor?
Responder Con Cita
  #8  
Antiguo 09-09-2007
PedroElFlaky PedroElFlaky is offline
Miembro
 
Registrado: sep 2007
Posts: 11
Poder: 0
PedroElFlaky Va por buen camino
Hola,

he descubierto lo que me sucede pero no sé cómo hacerlo bien,
mi programa se comporta como si el código de la dll lo hubiera implementado en una aplicación normal y no en una dll de las que es necesario para este tipo de hooks. Y creo que se está compilando la dll dentro del ejecutable de la aplicación.
Podrías decirme exactamente como se hace.

Lo que yo hice es lo siguiente:
Primero creé un proyecto para la dll, luego en otra carpeta cree el proyecto para la aplicación y luego puse los ficheros de ambos en la misma carpeta.
Estoy usando "declspec(dllexport)" en la dll para exportar HookOn y HookOff y en la aplicación estoy usando "declspec(dllimport)" para importarlas, además tengo en el proyecto de la aplicación el archivo con el código de la dll porque si no lo ponía me salía un error por usar "declspec(dllimport)".

Saludos
Responder Con Cita
  #9  
Antiguo 09-09-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Cita:
Empezado por PedroElFlaky Ver Mensaje
-si las variables globales son una copia diferente para cada aplicación que llama a mi dll, no estaría también la variable "MiHook" sin inicializar?
Exacto, la variable MiHook también estaría sin inicializar

Cita:
Empezado por PedroElFlaky Ver Mensaje
-al pasar de una aplicación a otra, las variables globales de la dll para mi aplicación, se resetean o cuando vuelva a mi aplicación conservarán su valor?
Cuando se vuelve a tu aplicación, la variables conservan su valor.

Veo que has desechado la idea de WH_KEYBOARD_LL, este hook captura las teclas de todos los procesos, solo que es mas fácil de implementar. Pero si lo quieres hacer por las malas no te queda mas que mapear las variables en memoria, hay varios ejemplos en el foro y fuera de el, pero ahora mismo solo encuentro este que puede orientarte:
http://www.clubdelphi.com/foros/showthread.php?t=37902
Responder Con Cita
  #10  
Antiguo 10-09-2007
PedroElFlaky PedroElFlaky is offline
Miembro
 
Registrado: sep 2007
Posts: 11
Poder: 0
PedroElFlaky Va por buen camino
Hola a todos,

comento los progresos y las dudas que me corroen:

La dll ya no deja de funcionar al cambiar la otra aplicación, por una parte quité lo de pasar_handle_a_dll() y por otra parte como lo comenté en otro post, importaba mal la dll y lo que hacía era incluir el código en mi aplicación y compilarlo dentro de ella, ahora lo hago bien y el programa y la dll van bastante bien.

Pero me gustaría muchísimo entender lo siguiente:
-probé lo de usar memoria global mapeada en donde almaceno el handle de la ventana de mi aplicación, y también probé a usar FindWindow(), lo primero funciona perfecto pero no entiendo por qué lo segundo solo envía mensajes a mi aplicación cuando no está minimizada

-comprobé que efectivamente para las demás aplicaciones MiHook está sin inicializar, pero aun así funciona bien, y de hecho en la mayoría de ejemplos que he visto, está como hago yo que se inicializa MiHook al llamar a HookOn() y por tanto solo se hace una vez al llamarla desde mi aplicación
Responder Con Cita
  #11  
Antiguo 11-09-2007
PedroElFlaky PedroElFlaky is offline
Miembro
 
Registrado: sep 2007
Posts: 11
Poder: 0
PedroElFlaky Va por buen camino
Hola,

ya me puedo responder a las 2 cuestiones que me planteé:

-la respuesta a lo primero es que FindWindow() si funciona y es bastante más fácil de usar que el mapeo de memoria, qué opinais?, no me funcionaba al principio a mi porque tenía mi programa en un directorio con el mismo nombre y los mensajes se enviaban al directorio en lugar de enviarse a mi programa

-la respuesta a lo segundo es que como para instalar y desinstalar, MiHook si está inicializado, entonces va bien, y en el único lugar que uso MiHook sin inicializar es en Result := CallNextHookEx(MiHook, Code, wParam, lParam), pues comprobé que funciona perfectamente (y no sé por qué), si en lugar de eso pongo Result := CallNextHookEx(0, Code, wParam, lParam)

Saludos
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Por que no funciona SUM y otras funciones al jalarlo desde delphi? desve MySQL 2 11-06-2007 22:18:20
Abrir otras aplicaciones desde Delphi Moparova Varios 1 19-04-2007 21:47:30
Monitorear eventos de otras aplicaciones Marco A. Ruiz API de Windows 0 22-08-2006 21:41:59
Capturar errores de otras aplicaciones Borro API de Windows 1 21-10-2005 21:40:03
Problema al ejecutar las aplicaciones en otras maquinas Durbed Varios 1 09-08-2005 18:09:43


La franja horaria es GMT +2. Ahora son las 12:32:50.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi