Fórum Criar um Form na thread #294553
05/09/2005
0
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
Curtir tópico
+ 0Posts
05/09/2005
Bruno Belchior
Gostei + 0
05/09/2005
Massuda
Gostei + 0
05/09/2005
Bruno Belchior
Gostei + 0
05/09/2005
Massuda
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.
Gostei + 0
29/04/2006
Mmoreira
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
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)