evento de teclado

Pregunta Sin Miedo no te cortes cualquier cosa para empezar - Autoit se comienza facilmente.Para Ordenes o Comandos sueltos. Ver nota como preguntar.
Responder
torni
Mensajes: 11
Registrado: 12 Mar 2010, 18:02

evento de teclado

Mensaje por torni »

buenas a todos.

¿Como podria saber cuando se usa el teclado?
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: evento de teclado

Mensaje por Ximorro »

Hola,
hombre, nos gustan las preguntas concisas, ¡pero tanto!...

¿Qué quieres hacer? lo fácil es saber si se está apretando una tecla concreta, puedes poner un hotkey, usar la función KeyPress...
Hay una manera (un poco compleja) de ver si el usuario ha interactuado, aunque eso no sólo detecta el teclado, también el ratón (es por ejemplo lo que se puede usar para parar un salvapantallas)
Hay varias posibilidades, cuéntanos un poco mejor qué quieres ver y lo miramos.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
torni
Mensajes: 11
Registrado: 12 Mar 2010, 18:02

Re: evento de teclado

Mensaje por torni »

Lo que quiero es saber cuando es utilizado el teclado, en general.
Con ispressed se puede conseguir pero no creo que sea muy optimo.

Supongo que user32 dispone de algun metodo directo, pero no estoy muy puesto en su api, ni de momento he usado dllcall pero veo que tendre que hacerlo pq autoit no tiene estas funciones :smt001
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: evento de teclado

Mensaje por Chefito »

Hombre, con un bucle que te recorra todas las combinaciones que tiene ispressed no estaría tan mal.

Por supuesto hay otros métodos, pero mucho más complicados. Puedes hacerlo con hooks (ganchos) al teclado. Pon la palabra teclas en el buscador nuestro y mira las últimas páginas. Seguro que te interesa un código que tiene una función llamada _KeyProc. Busca mis post :smt003 .
Con esta forma podrías capturar todo el teclado en todo el windows.

Otra forma podría ser capturando los mensajes del teclado que manda el windows a tu aplicación (si es esto lo que te interesa), o a un control específico de tu aplicación. Entonces esta forma sería más adecuada que la anterior.
No te voy a engañar, también es dificil de hacer :smt024 . Mira cosas como Windows Message Codes en el índice de la ayuda. Ahí están practicamente todos los mensajes que puedes necesitar, entre ellos WM_KEYFIRST, WM_KEYDOWN, WM_KEYUP. Para saber como se capturan estos mensajes mira en la ayuda la función GUIRegisterMsg.

Si es de un control específico, puede que estén los mensajes en la categoría wm_command y wm_notify.

Ya te digo que esto es para gente que tiene ya un nivel bueno :smt024 . Utiliza la búsqueda de la ayuda, la del foro nuestro y la del ingles, investiga todo lo que te he dicho y a leer e intentar hacer algo :smt005 .

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: evento de teclado

Mensaje por Ximorro »

Yo la verdad es que no tengo clara la consulta exacta:
.- ¿Se trata de saber cuándo se usa el teclado pero da igual qué se pulse? Por ejemplo para hacer el típico "Pulse cualquier tecla para continuar".
.- ¿O se trata de ver qué teclas se están pulsando en cada momento? Para hacer algo diferente dependiendo de qué tecla es.

También puedes ser importante si queremos ver sólo las teclas que se pulsan en nuestro GUI o los eventos generales en Windows.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
torni
Mensajes: 11
Registrado: 12 Mar 2010, 18:02

Re: evento de teclado

Mensaje por torni »

Cualquier tecla. Simplemente saber en que momento se ha pulsado alguna tecla, la tecla pulsada es indiferente.
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: evento de teclado

Mensaje por Ximorro »

Bien, mira, hay una función en la API de Windows para ver si el usuario ha realizado alguna actividad. El caso es que esto caza tanto teclado como ratón. Si te da lo mismo que el ratón también afecte esto puede serte útil:
(Ejecútalo y presiona cualquier tecla, moviendo el ratón o pulsando botones del ratón también se activa)

Código: Seleccionar todo

$USER32 = DllOpen("user32.dll")
$previo = _GetLastInputInfo()
While 1
 	If _GetLastInputInfo() <> $previo Then
		$resp = MsgBox(1, "Te pillé", "¡TE HAS MOVIDO!" & @LF & "(Cancela para finalizar el programa)")
		If $resp = 2 Then ExitLoop
		$previo = _GetLastInputInfo()
	EndIf
WEnd
DllClose($USER32)

Func _GetLastInputInfo()
	;Devuelve los ticks de reloj desde la última interacción de usuario
	Local $struct = DllStructCreate("uint;dword")
	DllStructSetData($struct, 1, DllStructGetSize($struct))
	DllCall($USER32, "int", "GetLastInputInfo", "ptr", DllStructGetPtr($struct))
	Return DllStructGetData($struct, 2)
EndFunc
Para sólo teclado no veo equivalencia, aunque se podría montar, te lo miro...
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: evento de teclado

Mensaje por Ximorro »

Bueno, he modificado el anterior para que ignore los movimientos de ratón, a ver si este te gusta más :smt003

Código: Seleccionar todo

$USER32 = DllOpen("user32.dll")
$previo = _GetLastInputInfo()
$ratonPos = MouseGetPos()
While 1
	If _GetLastInputInfo() > $previo Then
		If ($ratonPos[0] = MouseGetPos(0)) AND ($ratonPos[1] = MouseGetPos(1)) Then
			;No ha movido el ratón, luego la intereacción ha sido con una tecla
			$resp = MsgBox(1, "Te pillé", "¡TE HAS MOVIDO!" & @LF & "(Cancela para finalizar el programa)")
			If $resp = 2 Then ExitLoop
		Else
			$ratonPos = MouseGetPos()
		EndIf
		$previo = _GetLastInputInfo()
	EndIf
	Sleep(150) ;Necesario para no saturar la CPU y para dar tiempo a detectar los cambios de ratón
WEnd
DllClose($USER32)

Func _GetLastInputInfo()
	;Devuelve los ticks de reloj desde la última interacción de usuario
	Local $struct = DllStructCreate("uint;dword")
	DllStructSetData($struct, 1, DllStructGetSize($struct))
	DllCall($USER32, "int", "GetLastInputInfo", "ptr", DllStructGetPtr($struct))
	Return DllStructGetData($struct, 2)
EndFunc
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: evento de teclado

Mensaje por Ximorro »

Y este sirve en un GUI concreto, ¡pero no puede tener controles!

Hay una manera pero es más bien complicada.
Pregunta a los expertos: ¿hay alguna manera de ver el mensaje $WM_KEYDOWN en un GUI con controles sin usar ganchos de teclado?
¿Por qué no funciona con controles?

Código: Seleccionar todo

#include <WindowsConstants.au3>
#include <GuiConstantsEx.au3>

$miGUI = GUICreate("Toca alguna tecla", 220,100)
;GUICtrlCreateLabel("¡Toca alguna tecla!", 10,10, 150)
;$btnCerrar = GUICtrlCreateButton("&Cerrar", 60,50, 100)
GUISetState()

$tecladoTocado = False
GUIRegisterMsg($WM_KEYDOWN,"_WM_KEYDOWN") ;¡No funciona con controles!

While 1
	Switch GuiGetMsg()
		Case $GUI_EVENT_CLOSE;, $btnCerrar
			ExitLoop
	EndSwitch
 	If $tecladoTocado Then
		$resp = MsgBox(1, "Te pillé", "¡TECLA PRESIONADA!" & @LF & "(Cancela para finalizar el programa)")
		If $resp = 2 Then ExitLoop
		$tecladoTocado = False
	EndIf
WEnd

Func _WM_KEYDOWN($hWnd, $Msg, $wParam, $lParam)
	$tecladoTocado = True
	Return $GUI_RUNDEFMSG
EndFunc
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
torni
Mensajes: 11
Registrado: 12 Mar 2010, 18:02

Re: evento de teclado

Mensaje por torni »

senkiu ximorro

Lo del idletime lo habia visto, existe una funcion en las udf que se llama _Timer_GetIdleTime que llama a GetLastInputInfo de la api
Responder