PDA

Ver la Versión Completa : Hook de Teclado + DLL


FeLiXxUcO
01-12-2005, 12:35:06
Hola queria preguntar si alguien me puede ayudar con este tema, estoy intentando que mi aplicacion, estando minimizada o en el trayicon, responda a una combinacion de teclas (CTRL + 1 y que cambie el color de un shape de su formulario por ejemplo) estando como ventana principal, cualquier otra aplicacion.

He visto que hay que crear una DLL y por medio de los Hooks de las apis hacerlo pro no se como.

Alguien me puede ayudar??

si no, al menos saber como tengo que declarar las funciones en la DLL y como poder llamarlas desde la aplicacion, tengo la inicializacion del hook en un DLL
pro no puedo llamarlas desde mi aplicacion, o no se como hacerlo.

Agradeceria cualquier ayuda
Muchas Gracias.

jachguate
01-12-2005, 15:27:58
seguramente te orientará lo escrito en este hilo y la unidad hooks.pas (http://www.clubdelphi.com/users/roman/antigua/hooks.php) de roman.

Hasta luego.

roman
01-12-2005, 16:16:09
Aunque algo más sencillo podría ser usar RegisterHotKey con la cual le indicamos al sistema que nos mande un mensaje cada vez que la tecla registrada se oprima, independientemente de si nuestra aplicación tiene o no el foco.

// Saludos

FeLiXxUcO
01-12-2005, 20:30:35
El problema de la documentacion que hay aqui y a lo que te refieres jachguate, es que esta en Delphi y no tengo ni idea, he tratado de traducirlo pro no lo consigi :(
¿A que te refieres Roman con RegisterHotKey? es un componente?
Si es un componente y lo que hace es mandarme un mesaje con la combinacion de teclas pulsada,que mi aplicacion actue en consecuencia, y luego devuelva el control a la aplicacion que estaba antes en primer plano me podria servir y mucho.
Es que para que te hagas una idea mi aplicacion hace de servidor. y trabajo con otra que hace de cliente, entonces tengo que poder hacer cambios en el servidor mediate esa una combinacion de teclas, para ver como responde el cliente, que es el que tengo que estar visualizando en todo momento. Espero que se entienda cual es el objetivo.
Muchas gracias a los dos por responder ;)

dec
01-12-2005, 23:28:48
Hola,

Algo así podría hacerse, más o menos, tratándose de Delphi:


unit UfrmPrincipal;

interface

uses
Forms, Windows, Messages, Dialogs;

type
TfrmPrincipal = class(TForm)
procedure FormCreate(Sender: TObject);
private
procedure AppMessage(var Msg: tagMSG; var Handled: Boolean);
end;

var
frmPrincipal: TfrmPrincipal;

implementation

{$R *.dfm}

procedure TfrmPrincipal.AppMessage(var Msg: tagMSG; var Handled: Boolean);
begin
if (Msg.message = WM_HOTKEY) then
begin
if (LOWORD(Msg.lParam) = MOD_CONTROL)
and (HIWORD(Msg.lParam) = Ord('O')) then
ShowMessage('Pulsaste las teclas "CTRL + O"');
end;
end;

procedure TfrmPrincipal.FormCreate(Sender: TObject);
begin
Application.OnMessage := AppMessage;
end;

initialization
RegisterHotKey(Application.Handle, GlobalAddAtom('MiHotKey'), MOD_CONTROL, Ord('O'));

finalization
UnregisterHotKey(Application.Handle, GlobalAddAtom('MiHotKey'));

end.

FeLiXxUcO
01-12-2005, 23:44:10
Muchas gasias dec
Aunque ya digo que en Delphi estoy un poco pez.. tratare de traducirlo y ya contare que tal ha ido.
Y si lo logro hacer funciona ya dejare el codigo.
gracias por vuestras respuestas :)

dec
02-12-2005, 00:03:27
Hola,

Más o menos: ;)



void __fastcall TForm1::FormCreate(TObject *Sender)
{
Application->OnMessage = AppMessage;
//
// 79 es el código ASCII de la letra "O". No he conseguido encontrar la función
// correspondiente a "Ord" (en Delphi) aquí en C++ Builder. He probado con
// Integer("O") y con Cardinal("0"), pero, no funciona, así que al cabo he optado
// por pasar como tercer parámetro de "RegisterHotKey" el número 79, que ya sabes
// lo que quiere significar. ;)
//
RegisterHotKey(Application->Handle, GlobalAddAtomA("MiHotKey"), MOD_CONTROL, 79);
}

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
UnregisterHotKey(Application->Handle, GlobalAddAtomA("MiHotKey"));
}

// Declarado en la cláusula "private" de "TForm1"
//
void __fastcall TForm1::AppMessage(tagMSG &Msg, bool &Handled)
{
if (Msg.message == WM_HOTKEY)
{
if ( (LOWORD(Msg.lParam) == MOD_CONTROL) && (HIWORD(Msg.lParam) == 79) )
ShowMessage("Pulsaste las teclas CTRL + O");
}
}


Edito: Adjunto un archivo para que veas "la cosa" funcionando. ;)

FeLiXxUcO
02-12-2005, 07:47:24
Muchas Gracias David, el fin de semana hare pruebas y ya te comentare ;)

FeLiXxUcO
05-12-2005, 01:08:22
Bueno David, he utilizado el codigo que me pusiste en mi aplicacion y hace exactamente lo que necesitaba asi que me ha venido de perlas. Solo una aclaracion, tal vez lo que querias buscar en cuanto a Ord("O") en c++ Builder creo que se hace asi: (int)'O' al menos lo uso asi y funciona.

RegisterHotKey(Application->Handle, GlobalAddAtomA("MiHotKey"), MOD_CONTROL, (int)'O');


De nuevo Agradecerte el codigo porque me ha venido genial ;)

dec
05-12-2005, 05:26:06
Hola,



(...) tal vez lo que querias buscar en cuanto a Ord("O") en c++ Builder creo que se hace asi: (int)'O' al menos lo uso asi y funciona.
Pues gracias por comentarlo, porque acaso pueda tenerlo en cuenta en su momento. Lo cierto es que probé con (Integer)"O" y con (Cardinal)"O" (creo recordar) y no funcionaba... Bueno. De todos modos me alegro de que te fuera bien el tema. Gracias de nuevo por tus comentarios a respecto. ;)

i_berbeu
08-02-2006, 17:26:37
Yo he probado eso del registerhotkey y no me ha funcionado la verdad
no me pilla la pulsacion de la tecla o
seguramente es porque no lo entiendo del todo o falta algo de codigo que no se poner...
a ver si alguien pudiera explicarme
Gracias

dec
09-02-2006, 06:50:52
Hola,

i_berbeu, no puede ayudársete si no das más datos, o eres más preciso. Decir:


Yo he probado eso del registerhotkey y no me ha funcionado la verdad


Sin decir qué es lo que no te ha funcionado; sin especificar qué error te aparece; sin referir el código fuente que estás tratando de utilizar... como comprenderás no es por no querer, es que así es muy complicado echarte una mano. ¿Verdad?


seguramente es porque no lo entiendo del todo o falta algo de codigo que no se poner... a ver si alguien pudiera explicarme


Seguramente así sea. Pero toma nota de lo que te digo más arriba. Y más aún toma nota del código fuente que más arriba en este Hilo tienes a tu disposición. No se explica exactamente qué se lleva a cabo, pero, funcionar, funciona. Así pues, algo debes estar haciendo mal, eso está más o menos claro y es lo más normal del mundo; sin embargo, sin especificar un poco más se hace complicado echarte una mano. ¿No te parece?

i_berbeu
12-02-2006, 19:59:53
bueno vamos a ver si me explico mejor en lo que me falla... yo pongo este codigo(en c++ builder 5)
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Application->OnMessage = AppMessage;
//
// 79 es el código ASCII de la letra "O". No he conseguido encontrar la función
// correspondiente a "Ord" (en Delphi) aquí en C++ Builder. He probado con
// Integer("O") y con Cardinal("0"), pero, no funciona, así que al cabo he optado
// por pasar como tercer parámetro de "RegisterHotKey" el número 79, que ya sabes
// lo que quiere significar. ;)
//
RegisterHotKey(Application->Handle, GlobalAddAtomA("MiHotKey"), MOD_CONTROL, 79);
}

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
UnregisterHotKey(Application->Handle, GlobalAddAtomA("MiHotKey"));
}

// Declarado en la cláusula "private" de "TForm1"
//
void __fastcall TForm1::AppMessage(tagMSG &Msg, bool &Handled)
{
if (Msg.message == WM_HOTKEY)
{
if ( (LOWORD(Msg.lParam) == MOD_CONTROL) && (HIWORD(Msg.lParam) == 79) )
ShowMessage("Pulsaste las teclas CTRL + O");
}
}

que es el que pusiste tu DEC
entonces segun lei, se supone que me deberia pillar la pulsacion de la tecla "o"
aunque mi formulario no tenga el foco. o teniendolo, me da igual....
el caso es que el evento onMessage me pilla en la variable Msg ciertos valores. entonces si miro esos valores en Msg.message tenemos valores del tipo 670, 610, 14, 1550 y cosas asi, que yo no entiendo como eso va a ser igual a VM_HOTKEY a menos que sea un tipo enumerado que no lo se
entonces, resulta que aunque pulse la "o" a mi el evento ese no me captura un mensage en el cual se meta dentro hasta el ShowMessage.

Espero haberme explicado bien con esto y a ver si me solucionais la duda alguno
Gracias