Logo Desarrollo


Subrutinas y funciones en AutoHotkey:

en cualquier lenguaje de programación, se pueden definir como un fragmento de código independiente que se ejecuta cuando se los llama y, cuando terminan, vuelven al punto del que fué llamado.
Son fundamentales para tener un código organizado, ya que evitamos repetir muchas veces las mismas acciones. También facilita su mantenimiento, porque al realizar algún cambio, lo haremos sobre ellas y no en las tantas acciones repetidas en el script.


Subrutinas:

La subrutina se ejecuta con el comando Gosub, y el nombre de la etiqueta.
Al ejecutarse realizará la acción de esa etiqueta, y al encontrar un return, continuará con la línea siguiente después de la llamada.

f1::
Gosub Sonido
Run Notepad
Return


Sonido:
SoundBeep,440,50
Return


En este ejemplo primero debería sonar un beep y luego abrirse el block de notas. Esto sucede porque la primer línea después del atajo es un gosub, el cual llevará al intérprete a la línea 6. Continuará su ejecución con la línea 7 donde se encuentra la instrucción Beep. Al encontrar un Return en la línea siguiente saltará al mismo lugar desde donde fué llamado continuando su ejecución en la línea 3, es decir, El comando Run.


Un ejemplo un poquito más complejo, aunque no verdaderamente muy práctico.

f1::
Gosub, Verificación
SendRaw NvdaSpeak(text)`n{`nreturn DllCall("nvdaControllerClient" A_PtrSize*8 ".dll\nvdaController_speakText", "wstr", text)`n}
Return


f2::
Gosub, Verificación
SendRaw NvdaSpeak("")
Send {Left 2}
Return


Verificación:
If WinActive("ahk_class Notepad")
Return
Else
{
MsgBox,0,,
(
Error.
Este atajo solo puede ser ejecutado en alguna ventana del block de notas.
)
}


Tanto el atajo f1 como f2, antes de ejecutar el SendRaw, envía a la etiqueta Verificación.
En esa etiqueta se encuentra un condicional if. Este comprueba si está activa la ventana cuyo nombre está entre paréntesis y comillas. Si está, realizará la acción que está inmediatamente debajo. Y al encontrar un Return, que es en realidad lo único que hay, vuelve al punto de la subrutina, y continúa su ejecución.
A través de else, indicamos que si no se cumple con la sentencia if, haremos lo que está debajo.
En este caso, un mensaje MsgBox. Aquí he hecho una pequeña trampa. Si luego del cerrar llave hubiese colocado un Return, luego de aceptar la ventana de MsgBox hubiese vuelto al gosub y continuaría la ejecución normalmente. Al dejarlo como último elemento del script, la subrutina se rompe, y no regresa.
Otra forma de romper una subrutina es a través de un Reload. Que reinicia el script,, por lo que tampoco continuaría la ejecución del mismo.


El comando SendRaw sirve para enviar texto literal, mas conveniente en estos casos por estar pasando signos que cumplirían otra función en un simple Send. El comando send de la línea 9 hace que la flecha izquierda, "Left", se ejecute 2 veces, "2". Para conocer las posibilidades del comando Send, pueden visitar la Publicación oficial

Descargar el ejemplo de subrutina


Funciones:

Siguiendo la línea de esta sección, que es no profundizar tanto en la sintácsis para no abrumar y dinamitar las ganas de aprender, vamos a trabajar en un uso práctico. Las funciones son realmente muy potentes y intentar abarcar todas sus posibilidades convertirían esta entrada en un testamento.


Las funciones usan el mismo concepto de la subrutina, aunque al poder recibir parámetros y enviar resultados sus posibilidades son considerablemente mayores.
Para crear una función primero debemos colocarle un nombre. Inmediatamente después, entre paréntesis, los parámetros que van a utilizarse. Por último, entre llaves, la, o las acciones a realizarse.


Un uso bastante común que suelo darle, y será el que voy a mostrar, es el de hacer click en algún lugar y que el NVDA verbalice algo referido a ese click.
Para este caso voy a usar 3 parámetros. La coordenada x, la coordenada Y, y el texto a verbalizar. Así que colocamos el nombre, y entre paréntesis separados por comas los parámetros a usar;
FunctionExample(xCoord,yCoord,Text)
Los parámetros en este caso, son variables, por lo que podemos elegir otro nombre si quisiéramos. Lo importante es el órden, ya que en la llamada a la función debemos respetar esta misma posición de parámetros que irán entre paréntesis.
Supongamos que necesitamos hacer click en las coordenadas 28, 53. Y que el NVDA pronuncie,
Abrir navegación. Para ello debemos escribir el siguiente código:

^+a::
FunctionExample(28,53,"Abrir navegación")
Return


Aquí hemos colocado el nombre de la función que hemos llamado. El primer parámetro entre paréntesis es la coordenada x, el segundo, la coordenada y. Y el último, que siempre debe ir entre comillas cuando sea un texto literal, lo que va a verbalizar el NVDA cuando ejecutemos esta acción.
Ahora armemos la función:

FunctionExample(xCoord,yCoord,text) {
Click, %xCoord%, %yCoord%
return DllCall("nvdaControllerClient" A_PtrSize*8 ".dll\nvdaController_speakText", "wstr", text)
}


Cuando ejecutemos el atajo Control Shift a, El intérprete encontrará la llamada a una función. Tomará los parámetros que hay entre los paréntesis y se moverá a la función con ese nombre. Una vez en la función, comenzará a ejecutar las acciones línea a línea. En este caso, primero hay un comando click. como podrán observar, el primer parámetro del comando click que sería la cordenada x, tiene la llamada a una variable. Esto lo podemos saber porque está entre signos de porciento. Sucede lo mismo con el siguiente parámetro. Llamada a otra variable. Estas están definidas en el llamado a la función.
Una vez realizado el click, pasa a la línea siguiente. He colocado una espera, "Sleep", para que la verbalización no quede atrapada entre otras cosas que va a decir el NVDA.
Y finalmente toda la línea de una DLLCall que nunca recordaré de memoria. En este caso simplemente copien el texto y péguenlo en el lugar correspondiente. Esta línea toma el tercer parámetro de el llamado a la función que habíamos colocado entre comillas, y hará que el NVDA verbalice ese texto, siempre y cuando el archivo DLL esté colocado en el lugar correspondiente.
Todo esto tiene sentido si vámos a repetir la función más de una vez, caso en el cual simplemente podemos escribir el llamado a la función, colocar los parámetros correspondientes y listo. Inclusive, podríamos colocar las llamadas en una sola línea junto con el atajo., por ejemplo:

^+a::FunctionExample(28,53,"Abrir navegación")


Cuando el código se escribe en una sola línea, no es necesario colocar un Return al final.
El ejemplo que pondré para descargar es sobre algunos botones del block de notas.


Puede que suene un poco a chino todo esto, pero practicando se llega a buen puerto. Un buen artículo donde está explicado este tema y donde hay mas información es en la página de Gonduana. El siguiente link tiene el artículo sobre el tema. Subrutinas y funcionas en AutoHotkey


Descargar el ejemplo de función