Download com Barra de Progresso via UrlMon (Http)

            Depois de procurar na net, e não encontra um exemplo completo, resolvi implementar um aplicativo de download direto via url.

 

            Estava querendo algo para substituir a minha atualização de versão que era via ftp, para algo mais rápido e não dando muito erro de ficar travando o usuário, entre outras coisas, então comecei a procura na Net algo que pudesse me ajudar. Achei um exemplo que tem em todos os fóruns, e todos eles são idênticos, até os pingos nos “i”.

 

            Então vamos lá:

 

Primeiro vamos fazer um formulário parecido com a figura abaixo:

 

 

            Nele vamos utilizar os seguintes componentes:

 

. 2 TEdits

. 2 TLabel

. 2 TStaticText

. 2 TButton

. 1 Gauge

 

No Uses da interface declares as seguintes units: UrlMon, ShellApi, Activex.

 

Criaremos agora uma interface herdando de TInterfacedObject e IBindStatusCallback, sendo que esta classe deve vir logo após o uses da Interface.

Conforme o exemplo abaixo:

 

unit Uprincipal;

 

interface

 

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, UrlMon, ShellApi, Activex, ComCtrls, StdCtrls, Gauges;

 

 

Type

  TMeuObjetoInterface = class(TInterfacedObject, IBindStatusCallback)

  public

    function OnStartBinding(dwReserved: DWORD; pib: IBinding): HResult; stdcall;

    function GetPriority(out nPriority): HResult; stdcall;

    function OnLowResource(reserved: DWORD): HResult; stdcall;

    function OnProgress(ulProgress, ulProgressMax, ulStatusCode: ULONG;

      szStatusText: LPCWSTR): HResult; stdcall;

    function OnStopBinding(hresult: HResult; szError: LPCWSTR): HResult;

      stdcall;

    function GetBindInfo(out grfBINDF: DWORD; var bindinfo: TBindInfo): HResult;

      stdcall;

    function OnDataAvailable(grfBSCF: DWORD; dwSize: DWORD; formatetc:

      PFormatEtc;

      stgmed: PStgMedium): HResult; stdcall;

    function OnObjectAvailable(const iid: TGUID; punk: IUnknown): HResult;

      stdcall;

  end;

 

Logo após criarmos a interface TMeuObjetoInterface, pressionaremos as teclas CRTL+SHIF+C para o Delphi implementar as funções declaradas na sessão public.

 

Na “function OnProgress(ulProgress, ulProgressMax, ulStatusCode: ULONG;

      szStatusText: LPCWSTR): HResult; stdcall;” colocaremos o seguinte código:

 

function TMeuObjetoInterface.OnProgress(ulProgress, ulProgressMax,

  ulStatusCode: ULONG; szStatusText: LPCWSTR): HResult;

begin

  if Assigned(FrPrincipal) then

  begin

    Application.ProcessMessages;

    case ulStatusCode of

      1: FrPrincipal.StaticText1.Caption := 'Conectando em: '+ szStatusText;

      2: FrPrincipal.StaticText1.Caption := 'Conectado em: '+ szStatusText;

      3: FrPrincipal.StaticText1.Caption := 'Redirecionando para: '+ szStatusText;

      4: begin

           FrPrincipal.StaticText1.Caption := 'Fazendo Download: '+ szStatusText;

           FrPrincipal.barra.MaxValue := ulProgressMax;

           FrPrincipal.barra.Progress := ulProgressMax - ulProgress;

         end;

      5: begin

          FrPrincipal.StaticText2.Caption := 'Baixando: ' + FormatFloat('#.#,',

          ulProgress div 1024)

          + ' de ' +

          FormatFloat('#.#,', ulProgressMax div 1024) + 'Kb';

          FrPrincipal.barra.MaxValue := ulProgressMax;

          // FrPrincipal.barra.Progress := ulProgressMax - ulProgress; // descomente este para fazer decrecente

          FrPrincipal.barra.Progress := ulProgress;

 

         end;

      6: begin

           FrPrincipal.StaticText1.Caption := 'Final de Download: '+ szStatusText;

           FrPrincipal.StaticText2.Caption := 'Baixando: ' + FormatFloat('#.#,',

           ulProgressMax div 1024)

           + ' de ' +

           FormatFloat('#.#,', ulProgressMax div 1024) + 'Kb';

         end;

    end;

  end;

end;

 

No Botão de “Download” colocaremos o seguinte código:

 

procedure TFrPrincipal.Button1Click(Sender: TObject);

var

  MeuEstatus: TMeuObjetoInterface;

begin

  MeuEstatus := TMeuObjetoInterface.Create;

  URLDownloadToFile(nil, PChar(Edit1.Text), PChar(Edit2.Text), 0,MeuEstatus);

  StatusBar1.Panels[0].Text := 'Download concluído';

end;

 

No Botão de “Fechar”

 

procedure TFrPrincipal.Button2Click(Sender: TObject);

begin

  Application.Terminate;

end;

 

 

Simples assim.

 

 

Marco Banaggia

Analista de Sistemas

Delphi 2007