PDA

Ver la Versión Completa : Interrumpir un ciclo Repeat - Until


FGarcia
06-01-2009, 04:01:12
Hola!

Un saludo y un feliz año a todos los integrantes del club.

Mi pregunta basicamente es ¿como interrumpir le ejecucion de un ciclo Repeat - Until (son dos anidados) usando la tecla ESC?

basicamente el ciclo es:


repeat
repeat
until //lo que sea
until //lo otro

//intente esto pero no me hace nada. key es un var de tipo Char
repeat
repeat
if key = #27 then
break;
until //lo que sea que espere
if key = #27 then
break;
until //lo otro que espere


Como siempre agradeciendo su ayuda

DarkMan
06-01-2009, 04:12:00
Yo lo he probado y si funciona, el problema que veo que puede ser por el que no te funcione, es que no le das tiempo a la aplicación para leer el teclado, para leer la tecla esc, por lo que nunca te sale del ciclo.

FGarcia
06-01-2009, 05:00:51
mmmm....
coloque


sleep(100);



antes de la comprobacion de la tecla ESC pero no, no me funciona...

DarkMan
06-01-2009, 05:41:22
¿Cómo se supone que obtiene el valor la variable key? lo pregunto porque estas haciendo un ciclo en el que 'key' no actualiza nunca su valor. Por eso nunca saldrá del bucle, por muchos sleeps que pongas. Si key obtiene su valor por una llamada a una función, deberás intercalarla en el propio ciclo. Si pones el pedazo de código más ampliado, quizás pueda ayudarte mejor.

FGarcia
06-01-2009, 06:05:59
jajajaja tienes razon!!

Key nunca obtiene un valor!

Ah que bruto soy!!!:D:D

FGarcia
06-01-2009, 18:11:05
Continuo con esto, he cambiado el codigo por este otro que encontre en un hilo del club; el truco es de trucomania.


// Los datos se repiten y terminan con #13(CR)
repeat
repeat
//Rompe ciclo con ESC
Application.ProcessMessages ;
if GetKeyState(VK_Escape) and 128 = 128 then
break;
until FileRead(HandlePuerto,Num,1)=1;
//Rompe ciclo con ESC
Application.ProcessMessages ;
if GetKeyState(VK_Escape) and 128 = 128 then
break;
until Num = Terminador; // Final de cadena anterior


Segun que funciona en los bucles, pero no, no me ha funcionado, es mas no logro entender la logica: GetKeyState regresa un smallint que es el equivalente de la tecla pulsada pero ¿que hace el AND 128 = 128?

Una manita...

Fenareth
06-01-2009, 18:17:09
....

Segun que funciona en los bucles, pero no, no me ha funcionado, es mas no logro entender la logica: GetKeyState regresa un smallint que es el equivalente de la tecla pulsada pero ¿que hace el AND 128 = 128?

Una manita...

Pues por lo que se ve es una condición que siempre se cumple, siempre verdadera, no le veo, de buenas a primeras, mucho sentido...

roman
06-01-2009, 19:30:23
Segun que funciona en los bucles, pero no, no me ha funcionado, es mas no logro entender la logica: GetKeyState regresa un smallint que es el equivalente de la tecla pulsada pero ¿que hace el AND 128 = 128?


Para saber si una tecla está presionada o no, lo que importa es la información en el último bit del número que devuelve GetKeyState. La operación

GetKeyState and 128

aisla ese último bit ya que el 128 tiene 1 en el bit 7 y 0 en todos los demás (la operación AND es una operación booleana bit a bit).

En otras palabras, el resultado de la operación sólo puede ser 128 ó 0. De ahí la comparación con 128.

Yo he hecho la prueba y funciona si añades a tu ciclo una llamada a Application.ProcessMessages:


repeat
Application.ProcessMessages;

....

if GetKeyState(VK_ESCAPE) and 128 = 128 then
break;
until Num = Terminador


aunque yo lo pondría así:


repeat
Application.ProcessMessages;

....

until (Num = Terminador) or (GetKeyState(VK_ESCAPE) and 128 = 128)


Agrego

Otra cosa: el operador and tiene precedencia sobre el operador =. Por tanto, la expresión


GetKeyState(VK_ESCAPE) and 128 = 128


es equivalente a


(GetKeyState(VK_ESCAPE) and 128) = 128


De manera que no es que la condición siempre sea verdadera.

// Saludos

FGarcia
06-01-2009, 20:06:45
Lo siento si soy molesto pero ...no me funciona, modifique con la sugerencia que me diste Roman pero no, igual se queda en ciclo infinito. En si lo que estoy capturando es una cadena proveniente del COM1,el puerto ya esta abierto y comprobado que con esta rutina captura adecuadamente, sin embargo lo que quiero es poder romper el ciclo repeat - until con ESC en caso de que por alguna razon la cadena no pudiese ser capturada (puerto dañado, cadeana enviada diferente, etc). Actualmente solo desconecto el dispositivo que envia datos para poder simular una falla y usar ESC para salir del bucle.


// Los datos se repiten y terminan con #13(CR)
repeat
Application.ProcessMessages ;

repeat
Application.ProcessMessages ;
until (FileRead(HandlePuerto,Num,1)=1) or (GetKeyState(VK_ESCAPE) and 128 = 128);
until (Num = Terminador) or (GetKeyState(VK_ESCAPE) and 128 = 128); // Final de cadena anterior

Cad:='';

for n := 1 to longCadena do
begin
repeat
//Rompe ciclo con ESC
Application.ProcessMessages ;
until (FileRead(HandlePuerto,Num,1)= 1) or (GetKeyState(VK_ESCAPE) and 128 = 128);//lee un byte
Cad := Cad + chr(Num);
end;

cPeso := MidStr(Cad,3,8);
cUnits := MidStr(Cad,11,1);
cMode := MidStr(Cad,12,1);
cStatus := MidStr(Cad,13,1);

Fenareth
06-01-2009, 20:24:51
...
Agrego

Otra cosa: el operador and tiene precedencia sobre el operador =. Por tanto, la expresión

Código Delphi [-] (http://www.clubdelphi.com/foros/#)GetKeyState(VK_ESCAPE) and 128 = 128


es equivalente a

Código Delphi [-] (http://www.clubdelphi.com/foros/#)(GetKeyState(VK_ESCAPE) and 128) = 128


De manera que no es que la condición siempre sea verdadera.

// Saludos

Excelente hoy aprendí algo nuevo de "rebote" :p :)

FGarcia
07-01-2009, 00:06:10
OK, ya me funciono....el problema estaba en que como desconectaba el transmisor nunca recibia nada y en la sentencia :


repeat
until (FileRead(HandlePuerto,Num,1)=1) or (GetKeyState(VK_ESCAPE) and 128 = 128);


el FileRead espera recibir un caracter el cual al estar desconectado nunca llega. Si modifico la cadena enviada para que no cumpla lo que espero funciona bien con la tecla ESC. Ahora el problema cambia a como abortar el ciclo si no llega nada al puerto serie. Jeje Ese sera tema de otro hilo.

Gracias por la ayuda!!!