Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Esperar a que termine un proceso y luego continuar (https://www.clubdelphi.com/foros/showthread.php?t=88544)

pokexperto1 20-06-2015 01:08:41

Esperar a que termine un proceso y luego continuar
 
Tengo un codigo:
Código Delphi [-]
procedure Tjuego.hablarTimer(Sender: TObject);
begin
letra:=letra+1;
Memo.Text := Memo.Text + Copy(textomemo, letra, 1);
Hablar.Enabled := letra <= Length(textomemo);
acabado:=true;
end;

procedure Tjuego.Texto(texto: string);
begin
acabado:=false;
panelmemo.Visible:=true;
textomemo:=texto;
hablar.Enabled:=true;
end;

Yo llamo al procedimiento (pongo un ejemplo)
Código Delphi [-]
texto('Hola')
Como hago para que cuando termine ese texto pueda llamar a otro. No se si me explico.

Por ejemplo:
Código Delphi [-]
procedure boton;
begin
texto('Hola')
if acabado then//aquí iría el codigo de lo que os estoy hablando
texto('Adios');

pokexperto1 20-06-2015 01:20:44

Tambien he intentado detectar un imput del teclado pero parece que no se hacerlo...

ecfisa 20-06-2015 05:30:58

Hola pokexperto1.

Un modo de hacer lo que buscas es el siguiente, (agrega un TMemo y un TButton a un form):
Código Delphi [-]
...
implementation

//-------------------------------------------------------------
type
  TSpell = class(TThread)
  private
    FText    : string;
    FCount   : Integer;
    FTime    : DWORD;
    FInterval: Cardinal;
    Memo     : TMemo;
  public
    constructor Create; reintroduce; overload;
    procedure Execute; override;
    property Interval: Cardinal read FInterval write FInterval;
    property Text: string read FText write FText;
  end;

constructor TSpell.Create;
begin
  inherited Create(True);
  FTime  := GetTickCount;
  FCount := 0;
end;

procedure TSpell.Execute;
begin
  inherited;
  while FCount <= Length(FText) do
  begin
    if GetTickCount - FTime > Interval then
    begin
      Inc(FCount);
      Memo.Text := Memo.Text + FText[FCount];
      Application.ProcessMessages;
      FTime := GetTickCount;
    end;
  end;
end;

procedure SpellText(const Texto: string; Memo: TMemo; const Interv: Integer);
var
  spell: TSpell;
begin
  spell := TSpell.Create(True);
  try
    spell.Memo     := Memo;
    spell.Text     := Texto;
    spell.Interval := Interv;
    spell.Execute;
  finally
    spell.Free;
  end;
end;
//-------------------------------------------------------------

// Comenzar la escritura en el memo
procedure TForm1.btnStartClick(Sender: TObject);
begin
  Memo1.Clear;
  SpellText('Esperar a que termine un ', Memo1, 50);
  SpellText('proceso y luego continuar.', Memo1, 50);
  SpellText(#13#10+'Escribir una segunda linea.', Memo1, 50);
  SpellText(#13#10+'Y ahora una tercera...', Memo1, 50);
  //...
end;

Salida:


Saludos :)

Lepe 20-06-2015 14:23:57

wow !! curiosa la idea ecfisa.

Creo se debería usar "synchronize" cuando un thread se comunica con un elemento visual, pero bueno, es solo un test. Además, deberíamos tener en cuenta que si los textos no se mandan ordenados (porque se hace en un Paint de la ventana o desde un botón, etc) pueden salir desordenados.

A mí la idea que se me ocurre, mucho más cutre, es crear una cola de mensajes con un timer.

Para crear una pila tenemos varias formas . Existe desde Delphi 6 y anteriores.

Una vez tenemos encolados todos los mensajes, un timer es el que se encarga de comprobar si hay algo en la cola y procesa el mensaje. Si no hay nada, para el timer. Que se activará la próxima vez que se encole algo.

ecfisa 20-06-2015 16:58:56

Hola Lepe.

Es correcta tu observación. Usar el método Synchronize le da mas estabilidad al código, así que por más que haya sido solo un ensayo, se lo agregamos al amigo pokexperto1.
Código Delphi [-]
type
  TSpell = class(TThread)
  private
    FText    : string;
    FCount   : Integer;
    FTime    : DWORD;
    FInterval: Cardinal;
    Memo     : TMemo;
  public
    constructor Create; reintroduce; overload;
    procedure Execute; override;
    procedure WriteChar;
    property Interval: Cardinal read FInterval write FInterval;
    property Text: string read FText write FText;
  end;

constructor TSpell.Create;
begin
  inherited Create(True);
  FTime  := GetTickCount;
  FCount := 0;
end;

procedure TSpell.WriteChar;
begin
  Memo.Text := Memo.Text + FText[FCount];
end;

procedure TSpell.Execute;
begin
  inherited;
  while FCount <= Length(FText) do
  begin
    if GetTickCount - FTime > Interval then
    begin
      Inc(FCount);
      Synchronize(WriteChar);
      Application.ProcessMessages;
      FTime := GetTickCount;
    end;
  end;
end;

procedure SpellText(const Texto: string; Memo: TMemo; const Interv: Integer);
var
  spell: TSpell;
begin
  spell := TSpell.Create(True);
  try
    spell.Memo     := Memo;
    spell.Text     := Texto;
    spell.Interval := Interv;
    spell.Execute;
  finally
    spell.Free;
  end;
end;

Saludos :)

mamcx 20-06-2015 17:09:19

No entiendo porque el enruedo con un timer...

Delphi es un lenguaje imperativo... Hacer que una cosa siga a la otra es lo mas normal del mundo.

ecfisa 20-06-2015 18:17:14

Hola mamcx

Tal vez su proyecto necesite evitar las esperas activas entre la aparición de los caracteres y por eso recurrió al timer (no sé, se me ocurre...). De otro modo tenes razón en que no tiene sentido, se podría arreglar simplemente con Sleep.

Saludos :)

mamcx 20-06-2015 20:44:00

No.... para que sleep? para que esperar de forma fija? Si la operacion es secuencial, que complicacion hay?

ecfisa 20-06-2015 21:16:40

Cita:

Empezado por mamcx (Mensaje 493529)
No.... para que sleep? para que esperar de forma fija? Si la operacion es secuencial, que complicacion hay?

Por que interpreté que deseaba un efecto de teletipo, si no no le veo sentido a usar un timer... Ahora si lo que desea es poner un caracter detrás de otro, enseguida se lo solucionamos con un simple
Código Delphi [-]
 Memo1.Text := Texto;
:D

Saludos :)


La franja horaria es GMT +2. Ahora son las 15:33:27.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi