Olá pessoal, neste artigo será demonstrado como construir uma aplicação para efetuar downloads utilizando o componente TIdHttp da paleta Indy Clients que faz a conexão entre a aplicação e o servidor de onde pretendemos baixar o arquivo.

As paletas de componentes Indy (Indy Clients, Indy Servers, Indy I/O Handlers, Indy Intercepts, Indy Misc e Indy SASL) acompanham o Delphi há várias versões. Entre os componentes mais famosos e usados frequentemente podemos citar o conjunto (TIdMessage, TIdSMTP, TIdSSLIOHandlerSocket) utilizado para envio de e-mails através do Delphi.

Mas hoje não vamos falar sobre envio de e-mails, mas sim sobre como fazer downloads no Delphi utilizando o componente TIdHttp. É muito simples, os componentes Indy facilitam muito a vida dos desenvolvedores, principalmente no controle de tráfego dos bytes.

Vamos iniciar um novo projeto no Delphi. Para essa aplicação será necessário apenas um Form, onde serão adicionados os seguintes componentes no formulário:

Componentes Configurações das Propriedades
1 - TIdHttp Name = IdHttp
1 - TIdAntiFreeze Name = IdAntiFreeze
1 - TSaveDialog Name = dlgSave
1 - TEdit Name = edtUrl
1 - TCheckBox Name = ckbOpcao
Cursor = crHandPoint
1 - TProgressBar Name = pbProgresso
Visible = False
1 - TImage Name = img
Align = alTop
2 - TLabel 1 - Name = lbl1
 
1 - Name = lblStatus
Visible = False
3 - TBitBtn 1 - Name = btnBaixar
Caption = Baixar
 
1 - Name = btnCancelar
Caption = Cancelar
 
1 - Name = btnFechar
Caption = Fechar
Tabela 1. Lista de componentes e suas respectivas configurações

Entre esses componentes, cinco merecem atenção:

  • TEdit: nesse edit será informada a URL para download.
  • TIdAntiFreeze: esse componente impede o congelamento da aplicação, enquanto aguardamos o final do download.
  • TSaveDialog: servirá para indicar o caminho onde será gravado o arquivo que será baixado.
  • TProgressBar: exibirá o progresso do download, trazendo mais conforto para o usuário, pois o mesmo poderá acompanhar a evolução do download.
  • TCheckBox: disponibilizará a opção de fechar a aplicação após o termino do download.

Para deixar o visual mais agradável foi inserida uma imagem, o layout final do formulário segue abaixo:

Layout do formulário
Figura 1. Layout do formulário

Vamos começar codificando o evento OnClick botão “Fechar”, nesse evento simplesmente vamos fechar a aplicação.


Application.Terminate;
Código 1. Código para fechar a aplicação

No evento OnClick do botão “Cancelar” vamos desconectar o componente, assim estaremos “matando” o download.


IdHTTP.Disconnect; 
Código 2. Código para cancelar o Download

Antes de codificar o botão “Baixar” será necessário criar duas funções, uma para converter a porcentagem transcorrida do Download e outra para converter a quantidade em Kilobytes já baixados.

function TfrmPrincipal.RetornaPorcentagem(ValorMaximo, ValorAtual: real): string;
var
resultado: Real;
begin
resultado := ((ValorAtual * 100) / ValorMaximo);
Result    := FormatFloat('0%', resultado);
end; 
Código 3. Função para converter porcentagem transcorrida

function TfrmPrincipal.RetornaKiloBytes(ValorAtual: real): string;
var
resultado : real;
begin
resultado := ((ValorAtual / 1024) / 1024);
Result    := FormatFloat('0.000 KBs', resultado);
end; 
Código 4. Função para converter KiloBytes recebidos
Nota: As funções não serão explicadas, pois seu conteúdo é composto por operações matemáticas, a primeira com cálculo de porcentagem e a segunda com a conversão de bytes em kilobytes.

Essas funções serão chamadas em eventos específicos do componente TIdHttp, pois o mesmo possui alguns métodos e propriedades que facilitam o controle de tráfego dos downloads.

O primeiro evento do TIdHttp que vamos codificar é o OnWorkBegin, esse evento será disparado quando o componente inicia uma operação de leitura ou escrita. Sendo assim, a propriedade AWorkCountMax será preenchida com o número em Bytes aguardados para operação atual, nesse caso o tamanho do arquivo que pretendemos baixar, vamos também atribuir esse valor para a propriedade Max do TProgressBar.


procedure TfrmPrincipal.IdHTTPWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64);
begin
pbprogresso.Max := AWorkCountMax;
end; 
Código 4. Codificação do evento OnWorkBegin

Continuando no componente TIdHttp, agora vamos para o evento OnWork, esse evento é disparado sempre que a conexão chama operações de leitura ou gravação. Vamos utilizar esse evento para atualizar TProgressBar, a quantidade de bytes baixados e a porcentagem já baixada no caption do Formulário. Notem que estão sendo usadas as duas funções que criamos acima, passando o valor da propriedade AWorkCount que indica o número de bytes enviados ou no nosso caso recebidos.


procedure TfrmPrincipal.IdHTTPWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
begin
pbprogresso.Position := AWorkCount;
lblStatus.Caption    := 'Baixando ... ' + RetornaKiloBytes(AWorkCount);
frmPrincipal.Caption := 'Download em ... ' + RetornaPorcentagem(pbprogresso.Max, AWorkCount);
end;
Código 6. Codificação do evento OnWork

Para finalizar os eventos do TIdHttp, vamos codificar o evento OnWorkEnd. Esse evento é disparado quando é concluída uma operação de leitura ou escrita. No nosso caso quando finalizar o download, vamos desabilitar controles, emitir as mensagens de finalizado na tela e no caption do Formulário e verificar se o TCheckBox está marcado para finalizarmos a aplicação.


procedure TfrmPrincipal.IdHTTPWorkEnd(ASender: TObject; AWorkMode: TWorkMode);
begin
pbprogresso.Position := 0;
frmPrincipal.Caption := 'Finalizado ...';
lblStatus.Caption    := 'Download Finalizado ...';
pbprogresso.Visible  := false;
btnBaixar.Enabled    := true;
if ckbOpcao.Checked then
Application.Terminate;
end;
Código 7. Codificação do evento OnWorkEnd

Para finalizar vamos codificar o evento OnClick do botão “Baixar”, nesse evento vamos atribuir um filtro para TSaveDialog e criar um objeto do tipo TFileStream para manipularmos o arquivo que pretendemos baixar.

procedure TfrmPrincipal.btnBaixarClick(Sender: TObject);
var
fileDownload : TFileStream;
begin
dlgSave.Filter := 'Arquivos' + ExtractFileExt(edtUrl.Text) + '|*' + ExtractFileExt(edtUrl.Text);
dlgSave.FileName := 'Arquivo';
if dlgSave.Execute then
begin
fileDownload := TFileStream.Create(dlgSave.FileName + ExtractFileExt(edtUrl.Text), fmCreate);
try
pbprogresso.Visible := True;
lblStatus.Visible   := True;
btnBaixar.Enabled   := false;
IdHTTP.Get(edtUrl.Text, fileDownload);
finally
FreeAndNil(fileDownload);
end;
end;
end; 
Código 8. Código iniciar o Download

Antes de iniciar o download deixamos TProgressBar e lblStatus com a propriedade Visible = True, após a finalização do download a mesma propriedade do TProgressBar será alterada para false.

Agora vamos executar a aplicação, como exemplo será usado um link para download do editor de textos Notepad++.

Notem que no caption do formulário está sendo exibida a porcentagem transcorrida do download, e na tela a quantidade em kilobytes baixados. O botão “baixar” fica desabilitado enquanto existe uma operação de download em andamento.

Aplicação efetuando download
Figura 2. Aplicação efetuando download

Após finalizado o download, é exibida uma mensagem no caption do Formulário e na tela, o botão “Baixar” é habilitado novamente. Se o TCheckBox for marcado a aplicação será finalizada após o final do download.

Download finalizado
Figura 3. Download finalizado

Bom pessoal nesse artigo foi demonstrado como podemos utilizar o componente TIdHttp para desenvolver uma aplicação no Delphi para efetuar downloads. Foi possível observar como é fácil controlar o tráfego de dados e exibi-los na tela, usando apenas algumas operações matemáticas para convertê-los em um resultado mais apresentável para o usuário.

Espero que tenham apreciado e até a próxima.

Caso surja alguma dúvida meu e-mail é wllfl@ig.com.br. Fiquem à vontade também para usar a seção de comentários.

Abraço a todos!