Página 1 de 1

acceskey locales

Publicado: 27 Abr 2010, 01:27
por taoru
hola, estoy viendo si puedo crear un accesskey locales.
estoy utilizando actualmente el HotKeySet, pero esto crea teclas rapidas para todo el entorno windows, qe función debo utilizar para que solo sirva localmente?.

para que se entienda mi pregunta, quiero agregar a mi aplicación ver la ayuda, para ello, si estas adentro del software y presionas f1, te habre la ayuda, pero si presionas f1 en cualquier lado y no estas dentro del soft, no funciona.
como se puede hacer esto?, para detectar que tecla precionó solo si está dentro de la aplicación?.

dejo mi ejemplo de HotKeySet con el cual estoy provando.

Código: Seleccionar todo

Func ayuda()
MSGBox(0, "help!", "esta es la ayuda del soft")
ENDFUNC

Func salir()
MSGBox(0, "adios", "mundo")
    Exit 0
ENDFUNC


HotKeySet("{f1}", "ayuda")
HotKeySet("#{ESC}", "salir")

While 1
    Sleep(100)
WEnd
gracias!

Re: acceskey locales

Publicado: 27 Abr 2010, 04:48
por Fredinchy
Esto yo lo resolvería con la función WinActive(), así si la ventana está activa correrá la función ayuda o salir de lo contrario no hace nada. Pero si no me equivoco capturará las teclas pulsadas de todas formas, si estás en otro programa y la ayuda salta con f1 pues no hará nada porque el autoit captura esa tecla en todo momento. No sé cómo solucionar eso.. :smt017 no se me ha ocurrido nada.. :smt015

Código: Seleccionar todo

Func ayuda()
if WinActive("tu programa") then ;si la ventana está activa hace..
MSGBox(0, "help!", "esta es la ayuda del soft")
EndIf
ENDFUNC

Func salir()
if WinActive("tu programa") then ;si la ventana está activa hace..
MSGBox(0, "adios", "mundo")
    Exit 0
EndIf
ENDFUNC
Recuerda revisar los ejemplos de la ayuda siempre son muy útiles! :smt016

Saludos! :smt020

Re: acceskey locales

Publicado: 27 Abr 2010, 10:07
por Alastor
Este codigo es peligroso porque se puede usar facilmente para hacer un keylogger... de todas formas aqui tienes:

Código: Seleccionar todo

#include <Misc.au3>

Func ayuda()
	If WinActive("tu programa") Then ;si la ventana está activa hace..
		MsgBox(0, "help!", "esta es la ayuda del soft")
	EndIf
EndFunc   ;==>ayuda

Func salir()
	If WinActive("tu programa") Then ;si la ventana está activa hace..
		MsgBox(0, "adios", "mundo")
		Exit 0
	EndIf
EndFunc   ;==>salir

While 1
	If _IsPressed("70") Then ayuda() ; Si se presiona F1
	If _IsPressed("1B") Then salir() ; Si se presiona Escape
	Sleep(200)
WEnd

Re: acceskey locales

Publicado: 27 Abr 2010, 10:39
por xapu

Código: Seleccionar todo

hotkeyset("70","pressf1") Then pressf1()
Func pressf1()
HotKeySet(@HotKeyPressed)
if WinActive("tu programa") Then
MsgBox(0, "help!", "esta es la ayuda del soft") ; si nuestra ventana esta abierta, nos ejecuta esto
else ; si no...
Send(@HotKeyPressed) ;reenviamos el key f1
endif
EndFunc
seria algo asi.. io reo k ira pero eske aora no lo puedo probar

Re: acceskey locales

Publicado: 27 Abr 2010, 15:29
por Fredinchy
xapu escribió:

Código: Seleccionar todo

hotkeyset("70","pressf1") Then pressf1()
Func pressf1()
HotKeySet(@HotKeyPressed)
if WinActive("tu programa") Then
MsgBox(0, "help!", "esta es la ayuda del soft") ; si nuestra ventana esta abierta, nos ejecuta esto
else ; si no...
Send(@HotKeyPressed) ;reenviamos el key f1
endif
EndFunc
seria algo asi.. io reo k ira pero eske aora no lo puedo probar
Para que haces un send de @hotkeypressed si supuestamente es un programa para mostrar una ayuda.. no es necesario andar presionando la tecla.. Ya esto me huele a keylogguer.. Si quieres hacer tus malwares hazlos tú solo aquí no te vamos a ayudar.

Sayonara! :smt019

Re: acceskey locales

Publicado: 27 Abr 2010, 16:25
por Alastor
Fredinchy escribió:
xapu escribió:

Código: Seleccionar todo

hotkeyset("70","pressf1") Then pressf1()
Func pressf1()
HotKeySet(@HotKeyPressed)
if WinActive("tu programa") Then
MsgBox(0, "help!", "esta es la ayuda del soft") ; si nuestra ventana esta abierta, nos ejecuta esto
else ; si no...
Send(@HotKeyPressed) ;reenviamos el key f1
endif
EndFunc
seria algo asi.. io reo k ira pero eske aora no lo puedo probar
Para que haces un send de @hotkeypressed si supuestamente es un programa para mostrar una ayuda.. no es necesario andar presionando la tecla.. Ya esto me huele a keylogguer.. Si quieres hacer tus malwares hazlos tú solo aquí no te vamos a ayudar.

Sayonara! :smt019
envia otra vez la hotkey para no interrumpir otros programas

estan ignorando mi script :smt010

Re: acceskey locales

Publicado: 27 Abr 2010, 19:48
por Chefito
Alastor, nadie ignora tu programa. Te voy a decir más, es la mejor solución que he visto y la más lógica :smt002 . El único problema que puede tener acudir a esta función es que la tienes que estar llamando continuamente para que vea si pulsas las teclas....pero eso se soluciona muy facilmente, desde meterla en el bucle while...wend a llamarla desde un AdlibRegister.

Mmmmm....ya le habeis dado algunos buenos consejos. Muy bien :smt023 .

Yo voy a proponer una solución alternativa de las tantas que hay. Para que solo te afecten a tu ventana vamos a utilizar los mensajes de win que origina tu ventana. Vamos de caza de mensajes!!!! :smt005 :smt005 .

Utilizaremos los mensajes que envia wm_keydown para saber que teclas has pulsado cuando tu ventana está activa. Pero esto tiene algunas limitaciones, asi que me apoyaré en los mensajes originador por wm_keyup y wm_command para completar el script.
Tranquilos, es más facil de lo que parece :smt002 . Mirar el script que esta bastante bien explicado:

Código: Seleccionar todo

#include <WindowsConstants.au3>
#include <Misc.au3>
Global $keyWin=0
$hGUI = GUICreate("Prueba", 300, 100)
GUIRegisterMsg($wm_keydown, "WM_keydown")
GUIRegisterMsg($wm_keyup, "WM_keyup")
GUIRegisterMsg($wm_command, "WM_command")

GUISetState()

while 1
	Sleep(10)
WEnd

Func WM_keydown($hWnd, $iMsg, $iwParam, $ilParam)
	If $iwparam=0x70 Then ayuda()	;si pulsas la tecla f1 ejecuta la función ayuda
	If $iwparam=0x5b Then $KeyWin=1		;si pulsas la tecla Win $KeyWin=1
EndFunc
Func WM_keyup($hWnd, $iMsg, $iwParam, $ilParam)
	If $iwparam=0x5b Then $KeyWin=0		;si dejas de pulsar la tecla Win $KeyWin=0
EndFunc
Func WM_command($hWnd, $iMsg, $iwParam, $ilParam)
	If $KeyWin And $iwParam=2 Then salir()		;si la tecla de windows está siendo pulsada ($KeyWin=1) y al mismo tiempo pulsas la tecla ESC ejecuta salir.
EndFunc

Func ayuda()
MSGBox(0, "help!", "esta es la ayuda del soft")
ENDFUNC
Func salir()
MSGBox(0, "adios", "mundo")
    Exit 0
ENDFUNC
Si no entendeis algo decirlo.

Hay otra forma (la perfecta :smt003 ) de hacerlo, pero es con apis y es más complicada de hacer y de entender (si os animais os lo dejo a vosotros. Yo en su día ya me arté de hacer cosas con el teclado :smt005 ....no teneis más que ver los post hechos por mi en el foro sobre este tema) . Para que os hagais una idea de por donde pueden ir los tiros podeis buscar en el foro la api getkeystate, la cual creo que implementé yo en su día (ya ni lo se seguro :smt005 ) e hice muchos ejemplos con pulsaciones de teclado: http://www.emesn.com/autoitforum/search ... etkeystate
Mirar también este. Os dejo el post con el código más interesante, pero os recomiendo que os leais todo el tema: http://www.emesn.com/autoitforum/viewto ... tate#p3059

Mirar también el ejemplo en la ayuda de la función _WinAPI_SetWindowsHookEx.

Saludos.

Re: acceskey locales

Publicado: 27 Abr 2010, 20:44
por Alastor
@Chefito

buscando un poco he encontrado estas funciones, al parecer bastante interesantes:

Código: Seleccionar todo

; #FUNCTION# ====================================================================================================================
; Name...........: _GuiCtrlHotKey_Create
; Description ...: Create a HotKey control
; Syntax.........: _GuiCtrlHotKey_Create($hWnd, $sX, $sY[, $sWidth = 100[, $sHeight = 20[, $sStyle = 0]]])
; Parameters ....: $hWnd        - Handle to parent or owner window
;                  $iX          - Horizontal position of the control
;                  $iY          - Vertical position of the control
;                  $iWidth      - Control width
;                  $iHeight     - Control height
;                  $iStyle      - Control styles
; Return values .: Success      - Handle to the HotKey control
;                  Failure      - 0
; Author ........: R. Gilman (rasim)
; ===============================================================================================================================
Func _GuiCtrlHotKey_Create($hWnd, $sX, $sY, $sWidth = 100, $sHeight = 20, $sStyle = 0)
    $sStyle = BitOR($sStyle, $WS_CHILD, $WS_VISIBLE, $WS_TABSTOP)

    Local $hHotkey = _WinAPI_CreateWindowEx(0, "msctls_hotkey32", "", $sStyle, $sX, $sY, $sWidth, $sHeight, $hWnd)
    _SendMessage($hHotkey, $WM_SETFONT, _WinAPI_GetStockObject($DEFAULT_GUI_FONT), True)

    Return $hHotkey
EndFunc   ;==>_GuiCtrlHotKey_Create

; #FUNCTION# ====================================================================================================================
; Name...........: _GuiCtrlHotKey_Destroy
; Description ...: Delete the HotKey control
; Syntax.........: _GuiCtrlHotKey_Destroy($hWnd)
; Parameters ....: $hWnd        - Handle to the control
; Return values .: Success      - True
;                  Failure      - False
; Author ........: R. Gilman (rasim)
; ===============================================================================================================================
Func _GuiCtrlHotKey_Destroy($hWnd)
    Return _WinAPI_DestroyWindow($hWnd)
EndFunc   ;==>_GuiCtrlHotKey_Destroy

; #FUNCTION# ====================================================================================================================
; Name...........: _GuiCtrlHotKey_GetHotkey
; Description ...: Retrieve the virtual key code and modifier flags of a hot key from a HotKey control
; Syntax.........: _GuiCtrlHotKey_GetHotkey($hWnd)
; Parameters ....: $hWnd        - Handle to the control
; Return values .: Success      - Array with the following format:
;                  |[0] - virtual key code
;                  |[1] - modifier flags
;                  Failure      - False
; Author ........: R. Gilman (rasim)
; ===============================================================================================================================
Func _GuiCtrlHotKey_GetHotkey($hWnd)
    Local $iVal = _SendMessage($hWnd, $HKM_GETHOTKEY, 0, 0)

    If $iVal = 0 Then Return False

    Local $aRet[2]
    $aRet[0] = BitAND($iVal, 0x000000FF) ;The LOBYTE of the LOWORD is the virtual key code of the hot key
    $aRet[1] = BitShift($iVal, 8)        ;The HIBYTE of the LOWORD is the key modifier that specifies the keys that _
                                         ;define a hot key combination

    Return $aRet
EndFunc   ;==>_GuiCtrlHotKey_GetHotkey

; #FUNCTION# ====================================================================================================================
; Name...........: _GuiCtrlHotKey_SetHotkey
; Description ...: Set the virtual key code and modifier flags of an HotKey control
; Syntax.........: _GuiCtrlHotKey_SetHotkey($hWnd, $sVirtKey[, $sModKey])
; Parameters ....: $hWnd        - Handle to the control
; Return values .: Always returns zero
; Author ........: R. Gilman (rasim)
; ===============================================================================================================================
Func _GuiCtrlHotKey_SetHotkey($hWnd, $sVirtKey, $sModKey = 0)
    _SendMessage($hWnd, $HKM_SETHOTKEY, _MakeWord($sVirtKey, $sModKey), 0)
EndFunc   ;==>_GuiCtrlHotKey_SetHotkey

; #FUNCTION# ====================================================================================================================
; Name...........: _GuiCtrlHotKey_RegisterHotkey
; Description ...: Defines a system-wide hot key
; Syntax.........: _GuiCtrlHotKey_RegisterHotkey($hWnd, $sID, $sVirtKey, $sModKey)
; Parameters ....: $hWnd        - Handle to the main window that will receive messages generated by the hot key
;                  $sID         - The identifier of the hot key
;                  $sVirtKey    - The virtual-key code of the hot key
;                  $sModKey     - The modifier flags
; Return values .: Success      - 1
;                  Failure      - 0
; Author ........: R. Gilman (rasim)
; ===============================================================================================================================
Func _GuiCtrlHotKey_RegisterHotkey($hWnd, $sID, $sVirtKey, $sModKey)
    Local $iModKey = 0, $aRet

    If BitAND($sModKey, $HOTKEYF_SHIFT) Then $iModKey = BitOR($iModKey, $MOD_SHIFT)
    If BitAND($sModKey, $HOTKEYF_CONTROL) Then $iModKey = BitOR($iModKey, $HOTKEYF_CONTROL)
    If BitAND($sModKey, $HOTKEYF_ALT) Then $iModKey = BitOR($iModKey, $MOD_ALT)

    $aRet = DllCall("user32.dll", "int", "RegisterHotKey", _
                                            "hwnd", $hWnd, _
                                            "int", $sID, _
                                            "int", $iModKey, _
                                            "int", "0x" & Hex($sVirtKey, 2))

    If $aRet[0] <> 0 Then Return 1
EndFunc   ;==>_GuiCtrlHotKey_RegisterHotkey

; #FUNCTION# ====================================================================================================================
; Name...........: _GuiCtrlHotKey_UnregisterHotkey
; Description ...: Frees a hot key previously registered by the calling thread
; Syntax.........: _GuiCtrlHotKey_UnregisterHotkey($hWnd, $sID)
; Parameters ....: $hWnd        - Handle to the main window that will receive messages generated by the hot key
;                  $sID         - The identifier of the hot key
; Return values .: Success      - 1
;                  Failure      - 0
; Author ........: R. Gilman (rasim)
; ===============================================================================================================================
Func _GuiCtrlHotKey_UnregisterHotkey($hWnd, $sID)
    Local $aRet
    $aRet = DllCall("user32.dll", "int", "UnregisterHotKey", _
                                            "hwnd", $hWnd, _
                                            "int", $sID)

    If $aRet[0] <> 0 Then Return 1
EndFunc   ;==>_GuiCtrlHotKey_UnregisterHotkey

; #FUNCTION# ====================================================================================================================
; Name...........: _MakeWord
; Description ...: Creates a WORD value by concatenating the specified values
; Syntax.........: _MakeWord($sLoBite, $sHiByte)
; Parameters ....: $hWnd        - Handle to the control
;                  $sID         - The identifier of the hot key
; Return values .: The WORD value
; Author ........: R. Gilman (rasim)
; Remarks .......: Internal use only
; ===============================================================================================================================
Func _MakeWord($sLoBite, $sHiByte)
    Return BitOR($sLoBite, $sHiByte * 0x100)
EndFunc   ;==>_MakeWord
es posible que sirvan para este caso :smt002

Re: acceskey locales

Publicado: 28 Abr 2010, 00:26
por taoru
muchísimas gracias por toda la ayuda!, ahora lo probaré y cualquier cosa posteo el código a donde llegue.

que no se mal interprete, en ningún momento fue mi pregunta hacia un keylogger, eso está prohibido en este foro, y todos debemos leer las reglas (si las leí, xd).
pero también hay que tener en cuenta que hay personas ciegas que usan la pc, en este caso yo estoy desarrollando un cliente para una red social creada por personas ciegas, así que debe cuidar muy bien la accesibilidad, y como sabrán en este caso, se utiliza todo teclado, así que las teclas rápidas tienen que estar si o si.

por otro lado, mi pregunta se refería ya que si creo un hotkey con el f1, si vos te vas a otro soft después de abrir el cliente y presionas f1, se abriría la ayuda de mi cliente, y no del otro soft, sería invasivo. por eso lo del hotkey local.

ahora bien, hay bastante para probar, así que mano a la obra.
pruebo todo y después posteo hache como me fue con código en mano!.
saludos y gracias a todos!

Re: acceskey locales

Publicado: 28 Abr 2010, 01:08
por Chefito
Jejejeje, si parecen buenas las funciones. Habría que probarlas.
Una cosa, intenta poner todo el código porque sino dan fallos por todos lados.
A mi también me gusta referenciar el post original y el autor si es posible.

Las he buscado en el foro de habla inglesa y he encontrado este post (creditos a hunt): http://www.autoitscript.com/forum/index ... ntry693713

Pero te digo lo que antes, hay varias soluciones, unas mejores, otra peores y otras simplemente diferentes :smt002 . Hay que buscar la que mejor se adapte a tí, o simplemente la que te funcione bien :smt002 .

Por cierto Alastor, he editado el post anterior. Me equivoqué. Algo paso con el ordenador porque no cogía la virtualkey del Win. Por eso puse que no la aceptaba. Pero me extrañó mucho y después lo volví a probar y todo fue bien. Cosas de la informática (o será de windows :smt005 ).
O sea que la solución con _ispressed es totalmente funcional y la más sencilla. Poniendo una simple condición tienes la combinación que queremos:

Código: Seleccionar todo

If _IsPressed("1B") and _IsPressed("5B") Then salir() ; Si se presiona Escape
Saludos.

Re: acceskey locales

Publicado: 28 Abr 2010, 01:57
por Fredinchy
@Chefito no dejas de sorprenderme.. jaja menos mal que hay gente como tú para guiarnos :smt016

@Alastor no ignore tu código.. Si vi el tema lo vi entero no lo dudes, solo que no lo analicé prácticamente y me disculpo por juzgar mal tan rápido :smt022

@taoru muy bueno lo que estás haciendo sigue así.. ya tienes unos códigos para pelearte con el pc un rato :smt005

Saludos! :smt020

Re: acceskey locales

Publicado: 10 May 2010, 10:52
por Ximorro
Hum, el fallo del servidor de hosting se cargó mi respuesta. Creo de dejé bastante rollo pero haré un resumen:
Se pueden tener hotkeys locales al GUI con GUISetAccelerators

Lo que hace es asociar las teclas a controles del GUI, cuando se presionan esas teclas activa el evento que activa el control (como si hicieras clic, por ejemplo). Lo bueno del asunto es que no hace falta tener un control real, se pueden usar controles "virtuales", que se crean con GUICtrlCreateDummy. Estos controles no aparecen gráficamente en el GUI pero se pueden usar para cosas como esta de recibir el hotkey local.

GUISetAccelerators Se usa por ejemplo así:

Código: Seleccionar todo

Opt("GUICloseOnESC", 0)
Global $AccelKeys[1][2]=[["{ESC}", $btnMinimizar]]
GUISetAccelerators($AccelKeys)
Con esto minimizo mi GUI a la bandeja del sistema cuando se presiona ESC, pero sólo desde mi GUI (tengo un botón btnMinimizar que también hace eso así que lo uso, pero si no estuviera el botón habría usado un "dummy"). Presionar ESC en otra ventana hará lo que quiera esa ventana, pues no es un hotkey global. De la misma manera se puede asociar F1, y sólo saldrá nuestra ayuda cuando lo usemos en nuestra aplicación, no interferirá cuando se pulse F1 para sacar la ayuda de otro programa.

Re: acceskey locales

Publicado: 10 May 2010, 14:11
por Alastor
Gracias por repetir la explicación, precisamente la necesitaba en este momento :smt023
Entonces un control creado con 'GUICtrlCreateDummy' es un control invisible pero completamente funcional no?

Re: acceskey locales

Publicado: 11 May 2010, 09:23
por Ximorro
¡Se supone que sí! La verdad es que no lo he usado nunca pero se supone que para cosas como esta lo han puesto.
Te recomiendo intentarlo con el dummy, si eso no funcionara (¡debería!) quizás pueda usarse en un control oculto, si es que admite el disparo del evento a pesar de estar invisible...
Si no funciona invisible se puede ocultar de otra manera, por ejemplo poniendo un pequeño label detrás de un botón, el label no es clicable por el usuario porque está el botón delante, pero por programa sí...
Pero antes de hacer esas cosas más raras prueba con el dummy.

¡Ya nos cuentas!

Re: acceskey locales

Publicado: 14 May 2010, 21:33
por xapu
Fredinchy escribió:
xapu escribió:

Código: Seleccionar todo

hotkeyset("70","pressf1") Then pressf1()
Func pressf1()
HotKeySet(@HotKeyPressed)
if WinActive("tu programa") Then
MsgBox(0, "help!", "esta es la ayuda del soft") ; si nuestra ventana esta abierta, nos ejecuta esto
else ; si no...
Send(@HotKeyPressed) ;reenviamos el key f1
endif
EndFunc
seria algo asi.. io reo k ira pero eske aora no lo puedo probar
Para que haces un send de @hotkeypressed si supuestamente es un programa para mostrar una ayuda.. no es necesario andar presionando la tecla.. Ya esto me huele a keylogguer.. Si quieres hacer tus malwares hazlos tú solo aquí no te vamos a ayudar.

Sayonara! :smt019
???
renvio la key si el programa detecta k no esta activada nuestra gui si no pues sale lo de la ayuda...
tengo k aceptar k lo he sacado de un keylogger k ice ace tiempo, pero esto no es hacer ningun malware XD es intentar ayudar

de todos modos tio lo siento si te he ofendido