FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
Para momentaneamente el programa
Buenas. Me gustaria saber si se puede hacer de alguna forma o no lo siguiente: Resulta tengo mi programa haciendo un bucle y cuando clickeo un boton el programa no me hace caso por que esta haciendo las ordenes del bucle. Se puede para momentaneamente el bucle para que atienda la orden del boton y luego pueda seguir haciendo el bucle???? Muchas gracias.
|
#2
|
||||
|
||||
¡Buen día!
Kaesbu: Puedes utilizar el método ProcessMessages del objeto Application, llamándolo al final (y dentro) del ciclo. Por ejemplo: Código:
For I := 1 To 1000000 Do Begin ...(sentencias)... Application.ProcessMessages; End; Esto permite llevar a cabo ciclos de procesamiento que pueden ser algo lentos, sin que la aplicación deje de responder a las acciones del usuario. No obstante, debe uno tener cuidado al utilizar el método ProcessMessages, ya que éste puede desencadenar de nuevo el ciclo que actualmente se está ejecutando, resultando en una doble ejecución simultánea del mismo proceso. Ésto último se podría dar, por ejemplo, al ejecutar el ciclo en el evento OnClick de un botón, y luego durante el mismo, el usuario vuelve a presionar el mismo botón, el cuál es nuevamente accionado gracias a la llamada a Application.ProcessMessages. Para evitar este problema, existen varias soluciones (como sucede siempre en la programación ). Una de ellas es inhabilitar el botón mientras ejecuta su proceso: Código:
TForm1.Button1Click (Sender :TObject); Begin Button1.Enabled := False; Try For I := 1 To 1000000 Do Begin ...(sentencias)... Application.ProcessMessages; End; Finally { Se uitiliza Try..Finally para asegurar que el botón vuelva a habilitarse, aunque se eleve una excepción en el ciclo } Button1.Enabled := True; End; End; Espero esto sea de utilidad. Seguimos en contacto. Al González . Última edición por Al González fecha: 29-09-2003 a las 23:19:40. |
#3
|
||||
|
||||
Completando un poco lo que te indica Al González, para lograr el efecto de pausar el ciclo y luego
continuar podrías intentar algo como esto: Código:
var I: Integer; begin Pausa := false; for I := 1 to 50000 do begin while Pausa do Application.ProcessMessages; { Aquí el proceso que realices } Application.ProcessMessages; end; end; que el ciclo while no se ejecuta. El segundo ProcessMessages permite procesar otros eventos. Uno de ellos podría ser el click de un botón "Pausa" en donde pones la variable Pausa a true. Esto hará que la condición del ciclo while sea cierta y, como verás, es un ciclo que no terminará mientras Pausa sea true de manera que el ciclo for queda "suspendido". El ProcessMessages dentro del ciclo while permitirá que se sigan procesando los mensajes, por ejemplo el click de un botón "Continuar" en donde pondrías la variable Pausa a false haciendo que el ciclo while termine y continúe el ciclo for. Por otra parte, pienso que una solución "más seria" y sólida sería utilizar threads para ejecutar lo que haces dentro del ciclo for. // Saludos Última edición por roman fecha: 29-09-2003 a las 04:28:07. |
#4
|
||||
|
||||
Al González
Si puedes por favor edita tu mensaje para cortar la línea de comentario dentro del código que escribiste ya que causa que el texto de tu comentario y los demás no quepan en la pantalla. // Gracias Nota posterior Gracias Al, ahora ha quedado muy bien Última edición por roman fecha: 30-09-2003 a las 16:43:21. |
#5
|
|||
|
|||
Muchas gracias a los dos por contestar y hacerme las aclaraciones
sobre el tema. Poco a poco voy aprendiendo mas cosas sobre Delphi. Muchas gracias y un saludo. |
#6
|
|||
|
|||
Uffffff, lo he probado y se me han empeorado las cosas, ya que
el bucle lo que hace es bajar un archivo. El problema es que cuando llega al application.processmessages el buffer se vacia y el programa sale del bucle. Alguna idea? Gracias. |
#7
|
||||
|
||||
Para momentaneamente el programa: continuación
Cita:
Aquí te va una idea de cómo usar threads. El ejemplo es para copiar un archivo mostrando el avance en un ProgressBar pero puede servirte como punto de partida ya que la situación es similar: copiar bloques de archivos. Primero debes declarar un descendiente de TThread que se ocupará del copiado: Código:
type TCopyFileThread = class private ProgressBar: TProgressBar; // Barra de progreso procedure UpdateProgress; protected procedure Execute; override; public CopyFrom: String; // Archivo origen CopyTo: String; // Archivo destino BufferSize: LongInt; // Tamaño de cada bloque constructor Create(AProgressBar: TProgressBar); end; UpdateProgress se encargará de actualizar el ProgressBar. La implementación es así: Código:
constructor TCopyFile.Create(AProgressBar: TProgressBar); begin // Crear el hilo pero no iniciarlo inherited Create(true); ProgressBar := AProgressBar; BufferSize := 255; end; procedure TCopyFile.UpdateProgress; begin ProgressBar.StepBy(BufferSize); end; procedure TCopyFile.Execute; var Source, Dest: TFileStream; Buffer: Pointer; BytesRead: LongInt; begin Source := TFileStream.Create(CopyFrom, fmOpenRead); Dest := TFileStream.Create(CopyTo, fmCreate); GetMem(Buffer, BufferSize); ProgressBar.Max := Source.Size; try /* En este ciclo se hace el copiado Terminated es una variable del hilo que es false hasta que éste termine */ while not Terminated do begin BytesRead := Source.Read(Buffer^, BufferSize); Dest.Write(Buffer^, BytesRead); /* Es necesario llamar a UpdateProgress mediante Synchronize ya que UpdateProgress usda objetos del VCL */ Synchronize(UpdateProgress); if BytesRead < BufferSize then Terminate; end; finally Source.Free; Dest.Free; FreeMem(Buffer); end; end; Código:
CopyFile := TCopyFileThread.Create(ProgressBar1); CopyFile.CopyFrom := archivo origen; CopyFile.CopyTo := archivo destino; CopyFile.Resume; // Saludos En un botones adecuados de tu formulario usas los métodos CopyFile.Suspend para pausar el copiado CopyFile.Resume para continuar CopyFile.Terminate para cancelar el copiado Última edición por roman fecha: 30-09-2003 a las 16:44:01. |
|
|
|