Goto o func dentro de while

Pregunta Sin Miedo no te cortes cualquier cosa para empezar - Autoit se comienza facilmente.Para Ordenes o Comandos sueltos. Ver nota como preguntar.
Responder
dacu
Hacker del Foro
Mensajes: 106
Registrado: 20 May 2010, 00:09

Goto o func dentro de while

Mensaje por dacu »

Hola buenas, estoy buscando alguna función que me haga lo mismo que GOTO en baht o crear un While con funciones dentro pero por lo que veo no es posible.

Ponga el código.

Código: Seleccionar todo

#include <GDIPlus.au3>
#include <ScreenCapture.au3>


;###################################

;QUIERO UN GOTO o algo parecido AQUI

;####################################
$1 = @ScriptDir & "/fotos/1.jpg"


	_GDIPlus_Startup()
;$fname1=FileOpenDialog("First image","","All images(*.bmp;*.jpg;*.png;)")
$fname1 = @ScriptDir & "/captura.jpg"
If $fname1="" Then Exit
;$fname2=FileOpenDialog("Second image image","","All images(*.bmp;*.jpg;*.png;)")
$fname2 = $1
If $fname2= "" Then Exit
$bm1 = _GDIPlus_ImageLoadFromFile($fname1)
$bm2 = _GDIPlus_ImageLoadFromFile($fname2)


;################Variables##############
$dato1 = (dato1($bm1, $bm2))
;################Variables##############

_GDIPlus_ImageDispose($bm1)
_GDIPlus_ImageDispose($bm2)
_GDIPlus_Shutdown()


Func dato1($bm1, $bm2)

    $Bm1W = _GDIPlus_ImageGetWidth($bm1)
    $Bm1H = _GDIPlus_ImageGetHeight($bm1)
    $BitmapData1 = _GDIPlus_BitmapLockBits($bm1, 0, 0, $Bm1W, $Bm1H, $GDIP_ILMREAD, $GDIP_PXF32RGB)
    $Stride = DllStructGetData($BitmapData1, "Stride")
    $Scan0 = DllStructGetData($BitmapData1, "Scan0")

    $ptr1 = $Scan0
    $size1 = ($Bm1H - 1) * $Stride + ($Bm1W - 1) * 4


    $Bm2W = _GDIPlus_ImageGetWidth($bm2)
    $Bm2H = _GDIPlus_ImageGetHeight($bm2)
    $BitmapData2 = _GDIPlus_BitmapLockBits($bm2, 0, 0, $Bm2W, $Bm2H, $GDIP_ILMREAD, $GDIP_PXF32RGB)
    $Stride = DllStructGetData($BitmapData2, "Stride")
    $Scan0 = DllStructGetData($BitmapData2, "Scan0")

    $ptr2 = $Scan0
    $size2 = ($Bm2H - 1) * $Stride + ($Bm2W - 1) * 4

    $smallest = $size1
    If $size2 < $smallest Then $smallest = $size2
    $call = DllCall("msvcrt.dll", "int:cdecl", "memcmp", "ptr", $ptr1, "ptr", $ptr2, "int", $smallest)



    _GDIPlus_BitmapUnlockBits($bm1, $BitmapData1)
    _GDIPlus_BitmapUnlockBits($bm2, $BitmapData2)

    Return ($call[0]=0)

	EndFunc  ;==>CompareBitmaps

;############################################################################# Si coincide te salta el MsgBox "Coincide" si no lo vuelve a comprobar.


Select
     Case $dato1 = True ;1
         MsgBox(0, "Ejemplo", "Coincide")

     Case $dato1 = True ;2
         MsgBox(0, "Ejemplo", "No coincide, Comprobar otra vez")
		 ;volver a goto de arriba.
EndSelect

Gracias..
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Goto o func dentro de while

Mensaje por Chefito »

Que quieres un goto???? Macho macho, deja la programación spagetti (gotos y gosub) que es una técnica arcaica y malísima :smt021 . Menudos líos se hacían en los códigos :smt005 . Es mucho mejor la programación modular (por módulos) y la estructurada (funciones).
No se para que quieres hacer un goto. Llamando a funciones, que contengan el código que quieres reutilizar, las veces que quieras ya tienes solucionado lo de tener que ejecutar el código muchas veces.
dacu escribió:crear un While con funciones dentro pero por lo que veo no es posible.
Claro que no es posible, porque es una tontería.
Las funciones se deben de crear fuera del código......digamos principal. Se pueden crear por medio (una sola vez), pero el código se ensucia y te puedes liar. Las funciones solamente se leen una vez. Para que quieres leer una función muchas veces???? :smt017 . No tiene ningún sentido. Se leen una vez y luego las llamas las veces que quieras.

Creo que no tienes nada claros estos conceptos. No se que intentarás hacer, pero lo mejor es que nos lo digas para darte opciones.

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 ;).
dacu
Hacker del Foro
Mensajes: 106
Registrado: 20 May 2010, 00:09

Re: Goto o func dentro de while

Mensaje por dacu »

Buenas chefito, si XD ya leí que la programación espagueti es un lió XD y que el Autoit es lenguaje estructurado, lo que yo quiero es algo parecido al Goto, Digamos en una palabra que lo que quiero es, que si se cumple un criterio determinado se suba arriba del código y lo vuelva a hacer otra vez todo.

Lo malo de llamar funciones con call por ejemplo, es que tengo que llamar a todas, "unas 14" por k lo que quiero es comprobar todas continuamente hasta que por fin un valor cambia y ya se reconduce por otro lado.

lo malo es que cada función tiene las mismas variables y cuando inicio el scrip como lee de arriba abajo lee variables ejecuta la función, sigue bajando, lee las mismas variables con otros datos y ejecuta la función, y así continuamente hasta que se topa con el grupo "Select" y sus condiciones. Bien que pasa si ejecuto una func ahora desde hay, pues que esa función va a tener guardada las ultimas variables leídas y no me da los datos que quiero. jjaja lo unico que quiero es una funcion para tirar arriba y que vuelva a leer si se cumple "X" nada mas jaja..


Saludos. Pongo un ejemplo.

Código: Seleccionar todo

;#############################################################################

	_GDIPlus_Startup()
;$fname1=FileOpenDialog("First image","","All images(*.bmp;*.jpg;*.png;)")
$fname1 = @ScriptDir & "/captura.jpg"
If $fname1="" Then Exit
;$fname2=FileOpenDialog("Second image image","","All images(*.bmp;*.jpg;*.png;)")
$fname2 = @ScriptDir & "/captura1.jpg"
If $fname2= "" Then Exit
$bm1 = _GDIPlus_ImageLoadFromFile($fname1)
$bm2 = _GDIPlus_ImageLoadFromFile($fname2)


;################Variables##############
$var1= (var1($bm1, $bm2))
;################Variables##############

_GDIPlus_ImageDispose($bm1)
_GDIPlus_ImageDispose($bm2)
_GDIPlus_Shutdown()


Func var1($bm1, $bm2)

    $Bm1W = _GDIPlus_ImageGetWidth($bm1)
    $Bm1H = _GDIPlus_ImageGetHeight($bm1)
    $BitmapData1 = _GDIPlus_BitmapLockBits($bm1, 0, 0, $Bm1W, $Bm1H, $GDIP_ILMREAD, $GDIP_PXF32RGB)
    $Stride = DllStructGetData($BitmapData1, "Stride")
    $Scan0 = DllStructGetData($BitmapData1, "Scan0")

    $ptr1 = $Scan0
    $size1 = ($Bm1H - 1) * $Stride + ($Bm1W - 1) * 4


    $Bm2W = _GDIPlus_ImageGetWidth($bm2)
    $Bm2H = _GDIPlus_ImageGetHeight($bm2)
    $BitmapData2 = _GDIPlus_BitmapLockBits($bm2, 0, 0, $Bm2W, $Bm2H, $GDIP_ILMREAD, $GDIP_PXF32RGB)
    $Stride = DllStructGetData($BitmapData2, "Stride")
    $Scan0 = DllStructGetData($BitmapData2, "Scan0")

    $ptr2 = $Scan0
    $size2 = ($Bm2H - 1) * $Stride + ($Bm2W - 1) * 4

    $smallest = $size1
    If $size2 < $smallest Then $smallest = $size2
    $call = DllCall("msvcrt.dll", "int:cdecl", "memcmp", "ptr", $ptr1, "ptr", $ptr2, "int", $smallest)



    _GDIPlus_BitmapUnlockBits($bm1, $BitmapData1)
    _GDIPlus_BitmapUnlockBits($bm2, $BitmapData2)

    Return ($call[0]=0)

	EndFunc  ;==>CompareBitmaps

;#############################################################################

	_GDIPlus_Startup()
;$fname1=FileOpenDialog("First image","","All images(*.bmp;*.jpg;*.png;)")
$fname1 = @ScriptDir & "/captura.jpg"
If $fname1="" Then Exit
;$fname2=FileOpenDialog("Second image image","","All images(*.bmp;*.jpg;*.png;)")
$fname2 = @ScriptDir & "/captura2.jpg"
If $fname2= "" Then Exit
$bm1 = _GDIPlus_ImageLoadFromFile($fname1)
$bm2 = _GDIPlus_ImageLoadFromFile($fname2)


;################Variables##############
$var2= (var2($bm1, $bm2))
;################Variables##############

_GDIPlus_ImageDispose($bm1)
_GDIPlus_ImageDispose($bm2)
_GDIPlus_Shutdown()


Func var2($bm1, $bm2)

    $Bm1W = _GDIPlus_ImageGetWidth($bm1)
    $Bm1H = _GDIPlus_ImageGetHeight($bm1)
    $BitmapData1 = _GDIPlus_BitmapLockBits($bm1, 0, 0, $Bm1W, $Bm1H, $GDIP_ILMREAD, $GDIP_PXF32RGB)
    $Stride = DllStructGetData($BitmapData1, "Stride")
    $Scan0 = DllStructGetData($BitmapData1, "Scan0")

    $ptr1 = $Scan0
    $size1 = ($Bm1H - 1) * $Stride + ($Bm1W - 1) * 4


    $Bm2W = _GDIPlus_ImageGetWidth($bm2)
    $Bm2H = _GDIPlus_ImageGetHeight($bm2)
    $BitmapData2 = _GDIPlus_BitmapLockBits($bm2, 0, 0, $Bm2W, $Bm2H, $GDIP_ILMREAD, $GDIP_PXF32RGB)
    $Stride = DllStructGetData($BitmapData2, "Stride")
    $Scan0 = DllStructGetData($BitmapData2, "Scan0")

    $ptr2 = $Scan0
    $size2 = ($Bm2H - 1) * $Stride + ($Bm2W - 1) * 4

    $smallest = $size1
    If $size2 < $smallest Then $smallest = $size2
    $call = DllCall("msvcrt.dll", "int:cdecl", "memcmp", "ptr", $ptr1, "ptr", $ptr2, "int", $smallest)



    _GDIPlus_BitmapUnlockBits($bm1, $BitmapData1)
    _GDIPlus_BitmapUnlockBits($bm2, $BitmapData2)

    Return ($call[0]=0)

	EndFunc  ;==>CompareBitmaps

;#############################################################################


$bucle = 1

Select
     Case $var1= True ;1
         MsgBox(0, "Ejemplo", "la foto 1 coincide")

     Case $var2= True ;2
         MsgBox(0, "Ejemplo", "la foto 2 coincide")

	Case $bucle = 1
         MsgBox(0, "Ejemplo", "No coinciden ninguna foto")
         
         Ejecutar desde el principio el scrip

EndSelect
takuya2
Mensajes: 13
Registrado: 28 Ene 2011, 12:55

Re: Goto o func dentro de while

Mensaje por takuya2 »

Mete lo que quieras en una func, dentro de la func, al final, pones el nombre de la misma funcion. De esa forma una vez que llames la susodicha funcion, se repetira, y repetira, y repetira....
dacu
Hacker del Foro
Mensajes: 106
Registrado: 20 May 2010, 00:09

Re: Goto o func dentro de while

Mensaje por dacu »

gracias takuya2 voy a experimentar xD.


Vale EDITO:

Creo que no me e explicado bien, lo que vosotros me decís con pensamiento de " si esta claroooo " llama a la función y ya esta :smt043 "

Pero resulta que en este caso hay un problema, la función lo único que hace es comparar si una foto es igual a la otra y da un resultado "1" si coincide "0" si no, ejemplo
____________________________________________________________________
Func 1
Compara imagen 1 Con imagen 2

Func 2
Compara imagen 1 con imagen 3

Func 3
Compara imagen 1 con imagen 4

Select
Case func 1 = 1
Pincha en el botón 1

Case func 2 = 1
Pincha en el botón 2

Case func 3 = 1
Pincha en el botón 3

Case func 3 = 1
No existe coincidencia, comprueba otra vez, si yo llamo a la función
call (func1)
call (func2)
call (func3)
solo me va a comprobar si ahora coinciden, bien, ¿PERO? necesito que vuelva a venir a el "Select" este para que haga o no las cosas, y así continuamente.

Por eso no me sirve de nada llamar a la función xD.
______________________________________________________________________-

Espero que ahora me podáis entender bueno y yo a vosotros. :smt026


Saludos.
takuya2
Mensajes: 13
Registrado: 28 Ene 2011, 12:55

Re: Goto o func dentro de while

Mensaje por takuya2 »

y no has pensado en meter el Select en una funcion, y llamarla cuando se necesite?
dacu
Hacker del Foro
Mensajes: 106
Registrado: 20 May 2010, 00:09

Re: Goto o func dentro de while

Mensaje por dacu »

:smt017 Pense que no se podia hacer eso...

voy a probar.
Avatar de Usuario
BasicOs
Site Admin
Mensajes: 2085
Registrado: 21 Nov 2006, 19:24
Ubicación: El Internet - (Canarias, España)
Contactar:

Re: Goto o func dentro de while

Mensaje por BasicOs »

Vaya me recuerda a viejos tiempos del Basic.... jeje :smt015 :smt015 :smt017 :smt017
Si deseas volver a empezar y mandar hacia arriba del código como un GOTO puedes hacer por ejemplo un:


While 1
codigo
if pasa algo then ContinueLoop (va hacia arriba del while)
codigo
if paso algo salgo con ExitLoop
Wend

Ejemplo de la ayuda:

Código: Seleccionar todo

;Print all numbers from 1 to 10 except number 7
For $i = 1 to 10
    If $i = 7 Then ContinueLoop ;vuelve para arriba aquí
    MsgBox(0, "The value of $i is:", $i)
Next

Otra solución es como también te comenta Chefito y los compañeros, es usar funciones y cuando llegas a esa parte de código

xxx punto a volver con el "GOTO"
código
if pasa algo vuelvo a xxxx (pero llamo a una función que ejecute el código de arriba..)
código

Func mifuncion()  ;declarar las variables públicas previamente para que los cambios afecten fuera de la función
xxx punto a volver con el "GOTO"
código
EndFunc


Salu22:)

El código con el While, recuerda sacar las funciones de dentro del código que lo deja menos legible, mejor ponerlas al final de todo,
sería algo así más o menos:

Código: Seleccionar todo

#include <GDIPlus.au3>
#include <ScreenCapture.au3>


;###################################
While 1
	;QUIERO UN GOTO o algo parecido AQUI

	;####################################
	$1 = @ScriptDir & "/fotos/1.jpg"


	_GDIPlus_Startup()
	;$fname1=FileOpenDialog("First image","","All images(*.bmp;*.jpg;*.png;)")
	$fname1 = @ScriptDir & "/captura.jpg"
	If $fname1 = "" Then Exit
	;$fname2=FileOpenDialog("Second image image","","All images(*.bmp;*.jpg;*.png;)")
	$fname2 = $1
	If $fname2 = "" Then Exit
	$bm1 = _GDIPlus_ImageLoadFromFile($fname1)
	$bm2 = _GDIPlus_ImageLoadFromFile($fname2)


	;################Variables##############
	$dato1 = (dato1($bm1, $bm2))
	;################Variables##############

	_GDIPlus_ImageDispose($bm1)
	_GDIPlus_ImageDispose($bm2)
	_GDIPlus_Shutdown()



	;############################################################################# Si coincide te salta el MsgBox "Coincide" si no lo vuelve a comprobar.


	Select
		Case $dato1 = True ;1
			MsgBox(0, "Ejemplo", "Coincide")
			ExitLoop
		Case $dato1 = True ;2
			MsgBox(0, "Ejemplo", "No coincide, Comprobar otra vez")
			ContinueLoop
	EndSelect
WEnd

Func dato1($bm1, $bm2)

	$Bm1W = _GDIPlus_ImageGetWidth($bm1)
	$Bm1H = _GDIPlus_ImageGetHeight($bm1)
	$BitmapData1 = _GDIPlus_BitmapLockBits($bm1, 0, 0, $Bm1W, $Bm1H, $GDIP_ILMREAD, $GDIP_PXF32RGB)
	$Stride = DllStructGetData($BitmapData1, "Stride")
	$Scan0 = DllStructGetData($BitmapData1, "Scan0")

	$ptr1 = $Scan0
	$size1 = ($Bm1H - 1) * $Stride + ($Bm1W - 1) * 4


	$Bm2W = _GDIPlus_ImageGetWidth($bm2)
	$Bm2H = _GDIPlus_ImageGetHeight($bm2)
	$BitmapData2 = _GDIPlus_BitmapLockBits($bm2, 0, 0, $Bm2W, $Bm2H, $GDIP_ILMREAD, $GDIP_PXF32RGB)
	$Stride = DllStructGetData($BitmapData2, "Stride")
	$Scan0 = DllStructGetData($BitmapData2, "Scan0")

	$ptr2 = $Scan0
	$size2 = ($Bm2H - 1) * $Stride + ($Bm2W - 1) * 4

	$smallest = $size1
	If $size2 < $smallest Then $smallest = $size2
	$call = DllCall("msvcrt.dll", "int:cdecl", "memcmp", "ptr", $ptr1, "ptr", $ptr2, "int", $smallest)



	_GDIPlus_BitmapUnlockBits($bm1, $BitmapData1)
	_GDIPlus_BitmapUnlockBits($bm2, $BitmapData2)

	Return ($call[0] = 0)

EndFunc   ;==>dato1
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Goto o func dentro de while

Mensaje por Ximorro »

Estás mezclando declaraciones de funciones y código principal.
Pon el código de las funciones al final (los Func...EndFunc) y el código que las llama (que no está dentro de ningún Func) al principio.

Lo mejor será que nos expliques lo que quieres EN PALABRAS con detalle, y te explicaremos la forma de estructurar el código.
Bueno voy a intentarlo con lo que has explicado, entiendo que tienes una imagen y la quieres comparar con otras tres y hacer una tarea según a qué imagen corresponde. Lo que no entiendo es lo de repetir si no coincide con ninguna, pues aunque vuelvas a comprobar si no cambian las imágenes ¡el resultado será el mismo!

Yo usaría esta estructura (lo que no sea AutoIt lo pondré entre corchetes), fíjate que sólo usaría una función para la comprobación, lo que cambia es la imagen que le pasas, pero el proceso a realizar es el mismo, así que la función se reutiliza.

Código: Seleccionar todo

{Obtener $imagen1, $imagen2, $imagen3 e $imagen4}
Global $coinciden = False
While Not $Coinciden
	If _ComparaImagenes($imagen1, $imagen2) Then
		$coinciden = True
		{Realizar tareas cuando es como $imagen2}
	ElseIf _ComparaImagenes($imagen1, $imagen3) Then
		$coinciden = True
		{Realizar tareas cuando es como $imagen3}
	ElseIf _ComparaImagenes($imagen1, $imagen4) Then
		$coinciden = True
		{Realizar tareas cuando es como $imagen4}
	EndIf

	If NOT $coinciden Then
		{Si llega aquí es que no ha coincidido con ninguna imagen, así que supongo que las cambiarás de alguna manera,
		eso se haría aquí. Como $coinciden es falso repetirá el bucle. Este If es para cambiar las imágenes, la repetición
	        se hace por el While. Si hay coincidencia entonces $coinciden=True y entonces ni se entra en este IF ni se repite el
		While}
	EndIf
WEnd

Func _ComparaImagenes($var1, $var2)
	{Código que compara, si hay coincidencia devuelve TRUE, de lo contrario devuelve FALSE}
EndFunc
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Responder