Página 1 de 1

"Calculadora". Mi primer programa con autoit.

Publicado: 21 Sep 2011, 09:21
por chekok
Bueno, hay dejo el code de mi primera aplicación con autoit. La hice hace un tiempo en mis comienzos con Autoit (hace unos 2 meses).
Funciona perfectamente. Agradecería comentarios, no de la aplicación en sí, si no del modo de programar, si es correcto o se podría mejorar.

Tener en cuenta que soy novato en esto de Autoit (supe de su existencia hace 3 meses por un amigo) y no soy programador, ya que mi dedicación es el marketing online.

Código: Seleccionar todo

;Calculadora sencilla. by Chekok.2011

;includes necesarios.
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
#NoTrayIcon ;No muestra icono en la barra de tareas.

;GUI de la calculadora.
$calculadora = GUICreate("Calculadora", 506, 260, 245, 167, $WS_EX_TRANSPARENT)
GUISetBkColor(0xC0DCC0)
$display_txt = GUICtrlCreateInput("0", 8, 8, 409, 40, $ES_RIGHT)
GUICtrlSetFont(-1, 20, 800, 0, "Arial")
GUICtrlSetColor(-1, 0x00FF00)
GUICtrlSetBkColor(-1, 0x000000)
$memoria_group = GUICtrlCreateGroup("Memoria", 0, 48, 153, 49, BitOR($GUI_SS_DEFAULT_GROUP,$BS_FLAT))
$mr_btn = GUICtrlCreateButton("MR", 8, 64, 43, 25, $BS_FLAT)
GUICtrlSetBkColor(-1, 0x808000)
$m1_btn = GUICtrlCreateButton("M+", 56, 64, 43, 25, $BS_FLAT)
GUICtrlSetBkColor(-1, 0x808000)
$m0_btn = GUICtrlCreateButton("M-", 104, 64, 43, 25, $BS_FLAT)
GUICtrlSetBkColor(-1, 0x808000)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$ce_btn = GUICtrlCreateButton("CE", 424, 8, 75, 33, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0xFFFF00)
$operadores_group = GUICtrlCreateGroup("Operadores", 8, 104, 137, 121, BitOR($GUI_SS_DEFAULT_GROUP,$BS_FLAT))
$suma_btn = GUICtrlCreateButton("+", 16, 128, 51, 25, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0xA6CAF0)
$resta_btn = GUICtrlCreateButton("-", 16, 160, 51, 25, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0xA6CAF0)
$producto_btn = GUICtrlCreateButton("x", 80, 128, 51, 25, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0xA6CAF0)
$division_btn = GUICtrlCreateButton("/", 80, 160, 51, 25, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0xA6CAF0)
$igual_btn = GUICtrlCreateButton("=", 16, 192, 115, 25, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0x3A6EA5)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$numeros_group = GUICtrlCreateGroup("Números", 168, 48, 249, 177, BitOR($GUI_SS_DEFAULT_GROUP,$BS_FLAT))
$uno_btn = GUICtrlCreateButton("1", 176, 64, 75, 33, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0xFFFBF0)
$dos_btn = GUICtrlCreateButton("2", 256, 64, 75, 33, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0xFFFBF0)
$tres_btn = GUICtrlCreateButton("3", 336, 64, 75, 33, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0xFFFBF0)
$cuatro_btn = GUICtrlCreateButton("4", 176, 104, 75, 33, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0xFFFBF0)
$cinco_btn = GUICtrlCreateButton("5", 256, 104, 75, 33, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0xFFFBF0)
$seis_btn = GUICtrlCreateButton("6", 336, 104, 75, 33, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0xFFFBF0)
$siete_btn = GUICtrlCreateButton("7", 176, 144, 75, 33, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0xFFFBF0)
$ocho_btn = GUICtrlCreateButton("8", 256, 144, 75, 33, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0xFFFBF0)
$nueve_btn = GUICtrlCreateButton("9", 336, 144, 75, 33, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0xFFFBF0)
$cero_btn = GUICtrlCreateButton("0", 256, 184, 75, 33, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0xFFFBF0)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$especiales_group = GUICtrlCreateGroup("Especiales", 424, 56, 73, 169, BitOR($GUI_SS_DEFAULT_GROUP,$BS_FLAT))
$porcentaje_btn = GUICtrlCreateButton("%", 432, 80, 59, 33, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0x008080)
$decimal_btn = GUICtrlCreateButton(",", 432, 128, 59, 33, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0x008080)
$off_btn = GUICtrlCreateButton("Off", 432, 176, 59, 33, $BS_FLAT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetBkColor(-1, 0x008080)
GUICtrlCreateGroup("", -99, -99, 1, 1)
GUISetState(@SW_SHOW)

;Variables.
Local $numero[2]
$numero[0] = "0"
$numero[1] = "0"
$memoria = 0
$operador = 0
$resultado = 0

;Eventos de los botones.
While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $off_btn
			Exit
		Case $ce_btn
			reset()
		Case $cero_btn
			numeros(0)
		Case $uno_btn
			numeros(1)
		Case $dos_btn
			numeros(2)
		Case $tres_btn
			numeros(3)
		Case $cuatro_btn
			numeros(4)
		Case $cinco_btn
			numeros(5)
		Case $seis_btn
			numeros(6)
		Case $siete_btn
			numeros(7)
		Case $ocho_btn
			numeros(8)
		Case $nueve_btn
			numeros(9)
		Case $decimal_btn
			punto()
		Case $m1_btn
			mmas()
		Case $m0_btn
			mmenos()
		Case $mr_btn
			mr()
		Case $suma_btn
			suma()
		Case $resta_btn
			resta()
		Case $producto_btn
			producto()
		Case $division_btn
			division()
		Case $porcentaje_btn
			porcentaje()
		Case $igual_btn
			resultado()
	EndSwitch
WEnd

;Funciones.
Func reset()
	$numero[0] = 0
	$numero[1] = 0
	$operador = 0
	$resultado = 0
	GUICtrlSetData($display_txt, 0)
EndFunc
Func numeros($num)
	If $numero[0] == "0" Then
		$numero[0] = ""
		$numero[0] = $numero[0] & $num
		GUICtrlSetData($display_txt, $numero[0])
	ElseIf $numero[0] == "." Then
		$numero[0] = "0."
		$numero[0] = $numero[0] & $num
		GUICtrlSetData($display_txt, $numero[0])
	Else
		$numero[0] = $numero[0] & $num
		GUICtrlSetData($display_txt, $numero[0])
	EndIf
EndFunc
Func punto()
	If StringIsDigit ($numero[0]) Then
		numeros(".")
	EndIf
EndFunc
Func mr()
	$numero[0] = $memoria
	GUICtrlSetData($display_txt, $memoria)
EndFunc
Func mmas()
	If $memoria <> 0 Then
		$memoria = $memoria + Number(GUICtrlRead($display_txt))
	Else
		$memoria = GUICtrlRead($display_txt)
	EndIf
EndFunc
Func mmenos()
	If ($memoria <> 0) And (GUICtrlRead($display_txt)== 0) Then
		$memoria = $memoria - Number(GUICtrlRead($display_txt))
	Else
		$memoria = 0
	EndIf
EndFunc
Func suma()
	$numero[1] = $numero[0]
	$numero[0] = "0"
	$operador = "+"
EndFunc
Func resta()
	$numero[1] = $numero[0]
	$numero[0] = "0"
	$operador = "-"
EndFunc
Func producto()
	$numero[1] = $numero[0]
	$numero[0] = "0"
	$operador = "*"
EndFunc
Func division()
	$numero[1] = $numero[0]
	$numero[0] = "0"
	$operador = "/"
EndFunc
Func porcentaje()
	$numero[1] = $numero[0]
	$numero[0] = "0"
	$operador = "porcentaje"
EndFunc
Func resultado()
	If $operador <> "porcentaje" Then
		$preresultado = $numero[1] & $operador & $numero[0]
		$resultado = Execute($preresultado)
		GUICtrlSetData($display_txt, $resultado)
		$numero[0] = GUICtrlRead($display_txt)
	Else
		$preresultado = $numero[1] & "*("& $numero[0] & " / 100)"
		$resultado = Execute($preresultado)
		GUICtrlSetData($display_txt, $resultado)
		$numero[0] = GUICtrlRead($display_txt)
	EndIf
EndFunc


Re: "Calculadora". Mi primer programa con autoit.

Publicado: 21 Sep 2011, 09:44
por Ximorro
Pues leyendo tus comentarios anteriores me había dado la impresión de que eras un profesional de la programación ;-)

¡Enhorabuena por tu primer programa! Para ser el primero ya es bastante extenso.
Te hago algunas sugerencias que se me ocurren así a bote pronto:
Se puede compactar algo, fíjate que en los Case del Switch puede haber varios valores, así que los que ejecuten la misma acción se pueden agrupar, es decir, que:

Código: Seleccionar todo

      Case $GUI_EVENT_CLOSE
         Exit
      Case $off_btn
         Exit
puedes escribirlo como:

Código: Seleccionar todo

      Case $GUI_EVENT_CLOSE, $off_btn
         Exit
Además los de los números podemos hacer uso de la etiqueta del botón para compactar mucho el código, así el código:

Código: Seleccionar todo

      Case $cero_btn
         numeros(0)
            [...]
      Case $nueve_btn
         numeros(9)
podríamos ponerlo como

Código: Seleccionar todo

      Case $cero_btn, $uno_btn, $dos_btn, $tres_btn, $cuatro_btn, $cinco_btn, $seis_btn, $siete_btn, $ocho_btn, $nueve_btn
         numeros(GUICtrlRead($nMsg))
Na, una tontería, pero que simplifica la extensión del código y sigue siendo legible.

El porcentaje no hace falta ejecutarlo con Execute, pues el operador no es variable, así que:

Código: Seleccionar todo

      $preresultado = $numero[1] & "*("& $numero[0] & " / 100)"
      $resultado = Execute($preresultado)
se puede cambiar con:

Código: Seleccionar todo

	  $resultado = $numero[1] * $numero[0] / 100
Otra tontería es que los botones de los operadores y el igual salen cortados, creo que el texto es muy grande y tapa el borde. Igual sólo me sale porque tengo un XP, ahora no lo puedo probar en Vista. Pero si no es esa la intención quizás convenga hacer el texto un pelín más pequeño o los botones más grandes. Si no entiendes lo que quiero decir te pongo una captura de pantalla.

Una sugerencia ¿por qué no pones aceleradores de teclado para los números (y ya puestos quizás para los otros botones). Así se podrá usar con el teclado y el ratón.
Es como poner hotkeys pero específico a tu GUI, se hace con la función GUISetAccelerators, aquí lo explico un poco:
http://www.emesn.com/autoitforum/viewto ... a6a6#p8211
En la ayuda de la función tienes un ejemplo con dos botones, pero sólo hay que ir añadiendo pares ["tecla", control] y los puedes poner todos.

Re: "Calculadora". Mi primer programa con autoit.

Publicado: 21 Sep 2011, 10:38
por chekok
Gracias Ximorro por tus comentarios.
Voy a revisar el code y aplicar lo que me comentas para acortarlo y lo de el uso del teclado.

Gracias por el apunte del recorte en los botones, lo ví pero no caía porqué se producía, seguro que es por lo que comentas del tamaño de la fuente.

En lo referente a lo de que creías que era un profesional (gracias) se debe a que trabajo en una empresa de desarrollo de software y estoy a todas horas escuchando a mis compañeros (los programadores) y algo se me habrá pegado, jajaja.

Bueno, en otros hilos he insistido en lo de leer más la ayuda ya que es muy completa y fácil de entender. Esta app la hice acudiendo solo a la ayuda que incluye autoit, no ví siquiera código en la web, ni ejemplos parecidos ni nada, solo la ayuda y mi cerebro (además la hice en vacaciones y donde estuve no hay internet :smt019 ).

Espero conseguir llegar a ser un buen profesional de Autoit. Gracias.

Re: "Calculadora". Mi primer programa con autoit.

Publicado: 21 Sep 2011, 13:44
por BasicOs
Gracias y Felicidades por compartir el código, lo que hagas no tiene límites viendo tu ejemplo tienes capacidad para re-crear cualquier programa que desees o veas funcionando.
Salu22:)

Re: "Calculadora". Mi primer programa con autoit.

Publicado: 21 Sep 2011, 17:26
por Chefito
Jejeje, no está mal para un primer programa :smt023 .
El programa está bastante bien estructurado. Normalmente si quieres que sea totalmente ordenado y profesional, se deben de declarar las variables. Éstas, yo las suelo poner al principio, justo después de llamar a las librerías (las globales). Según creo recordar es lo correcto.

Respecto a lo de acortar el código, Ximorro ha estado fino :smt002 . No lo veo muy importante pero se podría acortar algo más utilizando los valores ids de los controles, ya que los botones desde el 1 hasta el 0 están consecutivos. Habría que tener cuidado en no meter ningún control por el medio:

Código: Seleccionar todo

      Case $uno_btn To $cero_btn
         numeros(GUICtrlRead($nMsg))
Para que fuese una buena calculadora, tendrías que controlar lo que introduces por el teclado. Solamente se deberían poder introducir los dígitos y los caracteres que utilicen las cifras numéricas. Esto se hace controlando los mensajes del input. Esto puede que sea algo más complicado. Tendrías que mirar la ayuda y ejemplo de la función _GUICtrlEdit_Create. Sería la mejor forma de hacerlo.
También ignora las cifras y demás signos que le introduces desde el teclado. Esto deberías mirarlo.

Saludos y sige así :smt023 .

Re: "Calculadora". Mi primer programa con autoit.

Publicado: 23 Sep 2011, 09:18
por Ximorro
Efectivamente la ayuda es realmente buena, y con eso y viendo ejemplos ya hechos (y modificándolos, lo que implica entenderlos bien) se aprende un montón.
Vas a llegar lejos, los programadores de tu empresa tienen un competidor ;-)

Yo el Edit simplemente lo haría no editable, si pones los aceleradores de teclas para todos los botones podrá escribir en el input sólo los caracteres adecuados. Como decía en otro post lidiar con la entrada de datos de un usuario puede ser una pesadilla, pensar en todas las posibilidades es casi imposible. Controlar la entrada con los botones será mucho más fácil que controlar que el texto libre que pone en el edit es correcto, y aún así con los aceleradores de teclas para los botones puede escribir absolutamente todas las expresiones correctas.
Y no es sólo por las teclas que ya no podrá poner (como letras u operadores que no toca) es que los pondrá bien, si ya los has controlado en el botón. Por ejemplo la coma decimal es un carácter correcto, ¡pero sólo puede aparecer una vez! Con el botón ya los estás controlando, pero si lo escribe directamente en el edit puede poner fácilmente números con dos comas decimales y cosas peores ;-)

Lo de las variables que comenta Chefito es muy importante, se trata de declarar las variables globales al principio del programa, y las locales al principio de cada función. Yo de hecho cuando el programa tiene cierta entidad, y me refiero incluso a programitas muy cortos, me OBLIGO a ello. Para "obligarse" se incluye al principio del programa la opción:
Opt("MustDeclareVars", 1)

Así si usas una varible que no está declarada da error. Al principio parece que sea más bien una molestia, pero es todo lo contrario. ¡QUITA MUCHOS DOLORES DE CABEZA!. Cambia por ejemplo en la función reset() el comando $operador = 0 por $operdor = 0. AutoIT no se queja pero de vez en cuando verás cosas raras, por ejemplo empieza a hacer una división pero antes de darle al igual le das al CE y haces el reset, seguidamente dale al igual... ahí tienes un error, sólo sabes que ha sido al darle al igual, ponte ahora a ver dónde está el problema, y resulta que era en el reset.
En cambio si fuerzas la declaración de variables, como al principio habrás hecho un Global $operador, en cuanto AutoIT vea el $operdor = 0 dará error diciéndote que la variable $operdor no ha sido declarada, y no es que haya que declararla, es que ves que era una variable ya declarada que se ha escrito mal. Repito, esto puede quitar muchos dolores de cabeza.

Otra manera de obligarse a declarar variables, y que da más opciones, es usar directivas de comprobación de Au3Check, yo uso a veces:
#AutoIt3Wrapper_AU3Check_Parameters=-d -w 3 -w 4
La opción -d es equivalente a Opt("MustDeclareVars", 1), además con -w 3 me avisa si estoy declarando una variable dos veces y con -w 4 si he declarado como local una variable global.

Además si te interesa puedes usar -w 5 para que te diga si has declarado variables locales pero no las usas (¡ya podía hacerlo también para las globales). Cuando estás desarrollando esto puede ser un rollo porque como tienes el código a mitad puede que no sean errores, simplemente que aún no has escrito ese código, pero yo a veces lo uso cuando he acabado el programa y me suele cazar alguna variable que he usado para hacer alguna prueba y luego ahí se ha quedado. Además es bastante listo, por ejemplo:

Código: Seleccionar todo

#AutoIt3Wrapper_AU3Check_Parameters=-d -w 3 -w 4 -w 5

ConsoleWrite(_Sum(2,3) & @CRLF)

Func _Sum($c, $d)
	Local $a
	$a = $c+$d
	Return $c+$d
EndFunc
Me dice que $a ha sido declarada pero no usada en la función. Y en realidad sí ha sido usada, vaya, le asigno un valor, ¡pero no uso ese valor y se da cuenta!

Re: "Calculadora". Mi primer programa con autoit.

Publicado: 23 Sep 2011, 10:18
por chekok
Gracias a todos por vuestros consejos.

En cuanto modifique el código lo publico para que veais los cambios.
Pero ahora estoy embarcado en otra aplicación que me puse a hacer ayer, la cual me pica más porque es un reto que me he hecho a mí mismo, un reproductor de TV TDT.
Ya os contaré

Viva Autoit!!!

Re: "Calculadora". Mi primer programa con autoit.

Publicado: 02 Jul 2012, 07:54
por rgracia
Alucinante!

Yo llevo casi una semana, se algo de programación y no se hacer ni la mitad.

Estás hecho un crack!

Re: "Calculadora". Mi primer programa con autoit.

Publicado: 05 Jul 2012, 10:28
por chekok
Gracias rgarcia, es lo que tiene autoit y la ayuda de los amigos del foro. Veras como con autoit en muy poco tiempo progresas mucho, y si no te lo crees, dentro de dos meses me comentas, seguro que para entonces ya has hecho una aplicación digna de admirar.

un saludo.