Problemas com Threads

Delphi

26/10/2007

Pessoal.

Não to entendendo o que tá acontecendo.

Uso Delphi 2007 com todas as atualizações.

procedure Thread_Restore.Criar_Ponto;
begin
frm_CreateRestore.lbl.Caption := ´Teste..´;
end;

procedure Thread_Restore.Execute;
begin
Synchronize(Criar_Ponto);
end;

procedure Tfrm_CreateRestore.FormShow(Sender: TObject);
var
ThrRestore: Thread_Restore;
begin
ThrRestore := Thread_Restore.Create(False)
end;


Ele cria a thread mas na hora de mudar o texto do caption, a Thread fecha.

O que pode ser?


Bernardop

Bernardop

Curtidas 0

Respostas

Massuda

Massuda

26/10/2007

Pelo código que você postou, é isso mesmo que deve ocorrer. O .Execute da thread apenas atualiza o label e depois, como não há mais nada a ser feito, a thread pára.


GOSTEI 0
Bernardop

Bernardop

26/10/2007

O problema é que o LABEL não está atualizando.


GOSTEI 0
Massuda

Massuda

26/10/2007

O problema é que o LABEL não está atualizando.
Você não disse isso antes.

frm_CreateRestore tem um valor válido? Ou seja, esse form é criado automaticamente pelo Delphi ou quando você cria manualmente o form usa essa variável para receber o form?


GOSTEI 0
Bernardop

Bernardop

26/10/2007

Todos são criado com o procedimento Create_Form(Tfrm_CreateRestore, frm_CreateRestore);


GOSTEI 0
Bernardop

Bernardop

26/10/2007

Qual seria o problema de usar threads - método syncronize com form´s criados dinamicamente?


GOSTEI 0
Massuda

Massuda

26/10/2007

Nenhum, desde que a variável frm_CreateRestore corresponda ao form criado dinamicamente.


GOSTEI 0
Bernardop

Bernardop

26/10/2007

Corresponde.

procedure Create_Form(Tfrm:TFormClass; frm:TForm);
begin
frm := Tfrm.Create(Application);
try
frm.Position := poScreenCenter;
frm.BorderStyle := bsNone;
frm.ShowModal;
finally
FreeAndNil(frm);
end;
end;

Muito estranho não estar sincronizando. O código do form é exatamente o que postei anteriormente.

Alguma sugestão?


GOSTEI 0
Massuda

Massuda

26/10/2007

Na verdade não. Nesse seu código, o frm é tratado como uma variável local, de modo que mudanças feitas em frm não são refletidas na variável que foi passada.

Experimente por um breakpoint depois do .Create e veja qual o valor de frm_CreateRestore; provavelmente será nil. Sem entrar no mérito do código em si, faltou por um [b:96ccf1c26e]var[/b:96ccf1c26e]...
procedure Create_Form(Tfrm:TFormClass; var frm:TForm);
...para esse seu código funcionar. Por causa disso, quando a thread é executada, deve estar dando um access violation (valor nil) o que encerra a thread.


GOSTEI 0
Bernardop

Bernardop

26/10/2007

Mas colocando esse var na frente,

como vou chamar o procedimento?

Já que chamar dessa maneira

Create_Form(Tfrm_CreateRestore, frm_CreateRestore);

não funcionaria mais.


GOSTEI 0
Massuda

Massuda

26/10/2007

...como vou chamar o procedimento?
Da mesma maneira que faz agora.

...não funcionaria mais.
Funciona.


GOSTEI 0
Bernardop

Bernardop

26/10/2007

O Delphi 2007 me retorna:

[DCC Error] E2033 Types of actual and formal var parameters must be identical


GOSTEI 0
Massuda

Massuda

26/10/2007

E2033 Types of actual and formal var parameters must be identical
Tinha esquecido que isso poderia ocorrer... Isso pode ser resolvido mudando um pouco sua Create_Form...
procedure Create_Form(Tfrm:TFormClass; var frm); 
var
  F: TForm;
begin 
  F := Tfrm.Create(Application); 
  Tfrm(frm) := F;
  try 
    F.Position := poScreenCenter; 
    F.BorderStyle := bsNone; 
    F.ShowModal; 
  finally 
    FreeAndNil(F); 
    Tfrm(frm) := nil;
  end; 
end;



GOSTEI 0
Bernardop

Bernardop

26/10/2007

Tanto a linha Tfrm(frm) := F; e a Tfrm(frm) := nil;

Ambos derão
[DCC Error] E2066 Missing operator or semicolon


GOSTEI 0
Massuda

Massuda

26/10/2007

Desculpe... nessas linhas, onde é Tfrm, devia ser TForm. então fica assim
procedure Create_Form(Tfrm:TFormClass; var frm); 
var 
  F: TForm; 
begin 
  F := Tfrm.Create(Application); 
  TForm(frm) := F; 
  try 
    F.Position := poScreenCenter; 
    F.BorderStyle := bsNone; 
    F.ShowModal; 
  finally 
    FreeAndNil(F); 
    TForm(frm) := nil; 
  end; 
end;



GOSTEI 0
Bernardop

Bernardop

26/10/2007

Era exatamente este o problema.

Muito obrigado!

Abração!

Bernardo.


GOSTEI 0
Bernardop

Bernardop

26/10/2007

Uma última dúvida:

Syncronize eu utilizo para atualizar valores do form.

Mas se eu quiser mudar o texto de um label várias vezes.

Terei que criar:

AtualizaTexto_Criar;
AtualizaTexto_Sair;

O Syncronize não aceita uma procedure com parametros não?

Exemplo:

Synchronize(AtualizaTexto(´Alowww!´));

Abraços!


GOSTEI 0
Bernardop

Bernardop

26/10/2007

Consegui!

Minha solução pro pessoal:

type
Thread_Restore = class(TThread)
private
MSG: String;
procedure AtualizaLabel;
protected
procedure Execute; override;
end;

procedure Thread_Restore.AtualizaLabel;
begin
frm_CreateRestore.lblTexto.Caption := MSG;
end;

procedure Thread_Restore.Execute;
begin
MSG := ´Texto´;

Synchronize(AtualizaLabel);
end;


GOSTEI 0
POSTAR