Fórum Criar um Form na thread #294553

05/09/2005

0

Olá pessoal,

Estou com um problema trabalhando com threads.
Tenho uma thread que faz um processamento demorado e lento e durante este processamento, gostaria de criar um Form e exibi-lo na tela durante este processamento e destruí-lo no final.
Queria que este form fosse criado diretamente pela Thread, mas quando o form é criado, recebo uma mensagem dizendo: ´[b:c6d681f311]Canvas does not allow drawing[/b:c6d681f311]´.

Esta mensagem só aparece quando executo o programa fora do Delphi. Quando executo dentro do delphi ela não aparece. Alguém poderia me ajudar a resolver este problema?

Estou colando abaixo o código da thread. Ele é bem simples.

type
  TThreadExemplo = class(TThread)
  private
    Obj : TObjqualquer;
    Form : TForm1;
  protected
    procedure Execute; override;
  public
    Constructor Criar;
  end;

implementation
{ TThreadExemplo }

constructor TThreadExemplo.Criar;
begin
  inherited create(true);
  Priority := tpLowest;
  Obj := TObjqualquer.create;
end;


procedure TThreadExemplo.Execute;
var erro : string;
begin
  try
    Form := TForm1.Create(nil);
    try
      Form.Show;
      Obj.processamentoqualquer(erro);
    finally
      Form.Close;
      FreeAndNil(Form);
      FreeAndNil(Obj);
    end;
  except
    on e : exception do
      application.MessageBox(pchar(e.Message),´erro´,MB_OK);
  end;
end;

Muito obrigado pela atenção.


Prgdelphi

Prgdelphi

Responder

Posts

05/09/2005

Bruno Belchior

não sou um exímio especialista em Thread´s porém acho q c vc deveria criar o contructor com o nome [b:5cd1938427]Create[/b:5cd1938427] em vez de [b:5cd1938427]Criar[/b:5cd1938427]...


Responder

Gostei + 0

05/09/2005

Massuda

...gostaria de criar um Form e exibi-lo na tela durante este processamento...
Para poder usar um elemento visual numa thread, você precisa fazer isso dentro de um procedimento chamado via [b:cd6481cba9]TThread.Synchronize[/b:cd6481cba9]; isso inclui criar, mostrar, atualizar e destruir o form. O mesmo vale para operações que envolvam banco de dados.


Responder

Gostei + 0

05/09/2005

Bruno Belchior

então o [b:9a2697da85]TThread.Synchronize[/b:9a2697da85] seria uma espécie de ´porta de comunicação´ com o mundo externo à Thread :?:


Responder

Gostei + 0

05/09/2005

Massuda

[quote:9ab162fcfe=´Bruno Belchior´]...seria uma espécie de ´porta de comunicação´ com o mundo externo à Thread ?[/quote:9ab162fcfe]Na verdade é um modo de sincronizar sua thread com a thread principal do programa.

Todo programa tem pelo menos uma thread (a thread principal). No caso da parte visual (o que inclui praticamente todo o código da VCL), ela é executada dentro da thread principal. O código da VCL não é [i:9ab162fcfe]thread safe[/i:9ab162fcfe] (ou seja, não pode ser executado em ambiente multi-thread) então a solução adotada foi possibilitar sincronizar qualquer thread com a thread principal.

Quando você executa TThread.Synchronize, sua thread encaixa na fila de mensagens da thread principal um pedido para ela executar o procedimento sincronizado (o que você passou para TThread.Synchronize). Isso garante que você consegue criar um form na sua thread num momento que a thread principal não esteja fazendo o mesmo, o que poderia, por exemplo, corromper a variável Screen.


Responder

Gostei + 0

29/04/2006

Mmoreira

Massuda,

Estou fazendo um sistema para fazer download de um arquivo em um FTP ultilizando IdFtp ( Indy 10 ). Estou usando uma Thread para que meu sistema nao fique congelado enquanto o arquivo é baixado. Nao tenho muita ou quase nenhuma experiencia com TThread ... Fiz esta com algumas dicas que peguei aqui no forum ...
Voce poderia dar uma olhada e me dizer o que nao esta certo e onde eu posso melhorar ... Outra coisa tambem queria criar uma rotina para cancelar o download ...


unit ufmPrincipal;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdFtp, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdExplicitTLSClientServerBase, ComCtrls;


type
  Thread_Baixa_Arquivo = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

type
  TfmPrincipal = class(TForm)
    btnBaixar: TButton;
    ProgressBar: TProgressBar;
    IdFTP1: TIdFTP;
    Label1: TLabel;
    btnCancelar: TButton;
    procedure btnBaixarClick(Sender: TObject);
    procedure IdFTP1WorkBegin(ASender: TObject; AWorkMode: TWorkMode;
      AWorkCountMax: Integer);
    procedure IdFTP1Work(ASender: TObject; AWorkMode: TWorkMode;
      AWorkCount: Integer);
    procedure IdFTP1WorkEnd(ASender: TObject; AWorkMode: TWorkMode);
    procedure btnCancelarClick(Sender: TObject);
  private
    Baixa_Arquivo : Thread_Baixa_Arquivo;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  fmPrincipal: TfmPrincipal;

implementation

{$R *.dfm}

procedure TfmPrincipal.btnBaixarClick(Sender: TObject);
begin

  if Baixa_Arquivo = nil then begin

    Baixa_Arquivo := Thread_Baixa_Arquivo.Create(true);
    Baixa_Arquivo.Resume;

  end else begin
    ShowMessage( ´Em execução!´ );

  end;

end;



procedure TfmPrincipal.IdFTP1WorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Integer);
begin
  ProgressBar.Position := 0;
  ProgressBar.Max := AWorkCountMax;  // 2507222
end;

procedure TfmPrincipal.IdFTP1Work(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Integer);
begin
  Application.ProcessMessages;
  ProgressBar.Position := AWorkCount;
  Label1.Caption := IntToStr( AWorkCount );
  Update;
end;

{ Thread_Baixa_Arquivo }

procedure Thread_Baixa_Arquivo.Execute;
begin

  fmPrincipal.IdFTP1.Host := ´www.meudominio.com.br´;
  fmPrincipal.IdFTP1.Username := ´logon´;
  fmPrincipal.IdFTP1.Password := ´senha´;
  fmPrincipal.IdFTP1.Connect;
  try
    fmPrincipal.IdFTP1.ChangeDir(´diretorio/´);
    fmPrincipal.IdFTP1.Get(´arquivo.zip´,´c:\arquivo.zip´,true);
  finally
    fmPrincipal.IdFTP1.Disconnect;
    FreeAndNil( fmPrincipal.Baixa_Arquivo );
  end;

end;

procedure TfmPrincipal.IdFTP1WorkEnd(ASender: TObject; AWorkMode: TWorkMode);
begin
  ProgressBar.Position := 0;
  Label1.Caption := ´0´;
end;

procedure TfmPrincipal.btnCancelarClick(Sender: TObject);
begin

  // fazer cancelamento do download -----

end;

end.


Vc pode me dar uma ajuda ...
valewss


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar