PDA

Ver la Versión Completa : Redireccionar el click a una tecla


Nicoasd
20-10-2006, 00:48:52
Buenas:
Quiero ver si alguien me puede decir como hacer para que al hacer click con el mouse me presione una tecla del teclado que yo desee

dec
20-10-2006, 00:56:17
Hola,

¿Cuando hagas clic con el "mouse" dónde, concretamente? ¿Y la pulsación de la tecla dónde se supone que ha de dirigirse?

Por favor, dedicad un poquito de tiempo a vuestras preguntas. Revisad la guía de estilo (http://www.clubdelphi.com/foros/guiaestilo.php) de los Foros.

seoane
20-10-2006, 01:01:14
Menos mal David que has respondido con un poco de sentido común, yo estaba pensando en hacer la gracia: "Si pones el ratón sobre el teclado y aprietas el botón con fuerza", ya lo ves algunos no tenemos gracia para contar chistes :(

Caral
20-10-2006, 01:01:34
Hola
Cada tecla tiene un numero por ejemplo la tecla enter= #13, la tecla tabular=#9, y asi con todas.
En el evento OnKeyPres del componente que desees pones algo asi:
Por ejemplo si quieres colocar el foco en un Boton del programa:
If Key = #13 Then
Button1.SetFocus;
Con esto al presionar la tecla enter colocaras el foco de control en el boton1.
Si por ejemplo quieres que el boton se presione al hacer enter:

If Key = #13 Then
Button1.Perform(WM_LButtonDown,0,0);
Sleep(250);
Button1.Perform(WM_LButtonUp,0,0);
Con esto al hacer enter presionaras el boton1.
No se si esto es lo que necesitas pero tal vez te sirva de ejemplo.
Saludos

dec
20-10-2006, 01:04:48
Hola,


"Si pones el ratón sobre el teclado y aprietas el botón con fuerza", ya lo ves algunos no tenemos gracia para contar chistes


Dice que no... :D :D

Nicoasd
22-10-2006, 01:16:18
Bueno:
Primeramente gracias a todos los que de algun modo me han dado una respuesta, especialmente Caral y tambien a los no me quiero olvidar de los humoristas:D que me dieron la idea de colocar el mouse sobre el teclado pero este metodo no me resulta muy comodo:cool:.

Lo que yo quiero hacer especificamente es crear un programa el cual lo este ejecutando en segundo plano, y que al prosionar click sobre cualquier lugar (con mi programa corriendo detras de otra aplicacion x) a el clik me lo tome como que estaria presionando una tecla...

Espero haber explicado mejor mi situacion esta vez, desde ya muchas gracias...

seoane
22-10-2006, 01:24:27
:D Veo que tienes sentido del humor. Veamos entonces que podemos hacer por ayudarte. Quieres que cuando hagas cilc sobre otra aplicación, la tuya reaccione simulando la pulsación de un tecla. Bien, eso podemos hacerlo, pero hay un par de cosas que necesitaría saber: ¿Nuestra aplicación debe reaccionar ante cualquier clic, sobre cualquier otra aplicación y sobre cualquier parte de la misma, o solo cuando se pulsa sobre una aplicación en concreto y una zona determinada de la misma? ¿Que tecla debemos simular que se pulsa? y por ultimo ¿la otra aplicación debe recibir el clic del ratón o debemos interceptarlo?

Nicoasd
22-10-2006, 01:41:39
Es asi:
lo que quiero hacer concretamente es un macro, o sea, que yo al estar jugando y queiera tomar pociones aga un click derecho y esto me lo tome como que estoy presionando la tecla U, si logro hacer eso despues quiero ver si le pongo un timer el cual al presionar el click me genere intervalos de U, o sea que este en ON y presione la U segun los intervalos que yo dese y al presionar nuevamente el click que se ponga en OFF los intervalos de U...

Gracias man!, ta muy bueno este foro...

seoane
22-10-2006, 01:59:04
Hablando de juegos podemos tener problemas, estos no suelen recibir las pulsaciones de teclado y ratón igual que los demás programas. Pero podemos probar, si no funciona, tendremos que pensar otra cosa.

La cosa funciona así, primero utilizamos un Hook que intercepte la pulsaciones de ratón, si la pulsación es del botón derecho simulamos una pulsación de teclado con la función keyb_event. Vamos con un poco de código:


// Esta constante no la tiene declarada delphi, ignoro porque
const
WH_MOUSE_LL = 14;

var
Hook: HHook;

// Esta funcion nos simula una pulsacion
procedure Pulsar(Key: Byte);
begin
keybd_event(Key, 0, 0, 0);
keybd_event(Key, 0, KEYEVENTF_KEYUP, 0);
end;

// Esta funcion se ejecuta cada vez que ocurre un evento del raton
function MouseProc(Code: Integer; WParam, LParam: DWORD): LRESULT; stdcall;
begin
if Code = HC_ACTION then
begin
// Comprobamos que estamos pulsando el boton derecho
if WParam = WM_RBUTTONUP then // o puede que WM_RBUTTONDOWN
begin
Pulsar(Ord('U'));
end;
end;
Result := CallNextHookEx(Hook, Code, WParam, LParam);
end;

procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// Eliminamos el Hook
if Hook <> 0 then UnhookWindowsHookEx(Hook);
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
// Colocamos un hook para interceptar los eventos del raton
Hook := SetWindowsHookEx(WH_MOUSE_LL, @MouseProc, HInstance, 0);
end;

seoane
22-10-2006, 04:54:34
:D Jeje, me corrijo a mi mismo. El evento keybd_event parece que no funciona con los juegos. Sin embargo contamos con la función SendInput que lo hace sin problemas. Aquí te dejo el código corregido, esta vez pulso la tecla al pulsar el botón derecho del ratón y suelto la tecla cuando suelto el botón. Probé el código con el Pinball de windows y parece que funciona:


const
WH_MOUSE_LL = 14;
KEYEVENTF_SCANCODE = $08;

var
Hook: HHook;

procedure SendKey(Code: Cardinal; KeyUp: Boolean);
var
Input: TInput;
begin
FillChar(Input,Sizeof(Input),0);
Input.Itype:= INPUT_KEYBOARD;
Input.ki.wScan:= MapVirtualKey(Code,0);
if KeyUp then
Input.ki.dwFlags:= KEYEVENTF_SCANCODE or KEYEVENTF_KEYUP
else
Input.ki.dwFlags:= KEYEVENTF_SCANCODE;
SendInput(1,Input,Sizeof(TInput));
end;

function MouseProc(Code: Integer; WParam, LParam: DWORD): LRESULT; stdcall;
begin
if Code = HC_ACTION then
begin
if WParam = WM_RBUTTONDOWN then
SendKey(Ord('Z'),FALSE)
else
if WParam = WM_RBUTTONUP then
SendKey(Ord('Z'),TRUE);
end;
Result := CallNextHookEx(Hook, Code, WParam, LParam);
end;


procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Hook <> 0 then UnhookWindowsHookEx(Hook);
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
Hook := SetWindowsHookEx(WH_MOUSE_LL, @MouseProc, HInstance, 0);
end;


Aquí te dejo todo montado

Nicoasd
23-10-2006, 19:49:08
muchas gracias man!

una masa el codigo que me pasaste, todabia estoy tratando de entender unas cositas pero ta muy bueno, como ultima consulta queria ver si me podes decir donde se pondria un timer o algo que lo que me produsca sea que cuando presione el click comience a presionar una tecla hasta que presione nuevamente el click y que deje de hacerlo,...porque yo puse un timer, pero lo que me hace es en un intervale me presiona muchas veces la 'u' pero yo quiero que presione hasta que aprete nuevamente el click,... porque en el juego me lo tomaba como que solamente apretaba una ves la 'U'...

desde ya gracias por tomarte el trabajo de habermelo enviado la ves pasada....

seoane
23-10-2006, 20:23:57
El secreto de simular pulsaciones de teclado es el intervalo entre que se presiona la tecla y se suelta, si este es muy corto algunos programa ni se darán cuenta de que la tecla se ha pulsado. En el siguiente ejemplo lo que hago es utilizar el evento WM_RBUTTONUP para activar o desactivar un Timer, dentro del evento del timer voy alternativamente presionando y soltando la tecla. Es solo un ejemplo se puede mejorar:

Revisa el zip para ver el código completo:

function MouseProc(Code: Integer; WParam, LParam: DWORD): LRESULT; stdcall;
begin
if Code = HC_ACTION then
begin
if WParam = WM_RBUTTONUP then
frmMain.Timer1.Enabled:= not frmMain.Timer1.Enabled;
end;
Result := CallNextHookEx(Hook, Code, WParam, LParam);
end;

procedure TfrmMain.Timer1Timer(Sender: TObject);
begin
if Abajo then
SendKey(Ord('Z'),TRUE)
else
SendKey(Ord('Z'),FALSE);
Abajo:= not Abajo;
end;

Nicoasd
23-10-2006, 20:54:58
ok, listo man!

Gracias por todo, no te jodo mas,...

Suerte,...Saludos

Nicoasd
30-10-2006, 19:04:59
Que rompe soy, no? :S

--------------------------------------------------------------------------------

bueno:
yo de nuevo 0.0 queria ver si me pueden solucionar otros problemitas, quiero hacer que cuando active los intervalos de 'Z' en algun butoon/label o algo diga el estado(on/off) o sea, si esta apretando la 'Z' o no,... bue, otra cosita que quiera hacer es que a 'Z' me lo tomo de una variable, eh probado ahcer de todo, pero no me sale, no se en que tipo de dato poner la variable(probe:string, integer, boolean,...) y nada me anda,...

gue,... desde ya muchas gracias,....