Zawieszanie się programu podczas pobierania

0

Witam,

mam problem z moim programem. Otóż mam taką procedurę (http://delphi.about.com/cs/adptips2003/a/bltip0903_2.htm):

procedure tform2.download;
begin
   with TDownloadURL.Create(self) do
   try
   application.ProcessMessages;
     progressbar1.Visible:=true;
     URL:=mod1;
     FileName := mod2;
     OnDownloadProgress := URL_OnDownloadProgress;
     ExecuteTarget(nil) ;
     finally
     free;
   end;

Niestety podczas pobierania pliku forma nie odpowiada. Jak zrobić aby program się nie zawieszał oraz czy da się zrobić przycisk "anuluj"?

0
  1. Użyj wątków
  2. Przecież masz jak byk:
 TDownloadProgressEvent = procedure(Sender: TDownLoadURL; Progress, ProgressMax: Cardinal; StatusCode: TURLDownloadStatus; StatusText: String; var Cancel: Boolean) of object;

Jak myślisz co sie stanie gdy zmienisz wartość parametru Cancel na True?

Cancel allows the event handler to cancel the download operation. On entry to the event handler, Cancel is false. If the event handler changes Cancel to true, the download operation is aborted.

0

Zrobiłem z wątkiem:

procedure Tdownolad.Execute;
begin
   with TDownloadURL.Create(self) do
   try
   application.ProcessMessages;
     progressbar1.Visible:=true;
     URL:=mod1;
     FileName := mod2;
     OnDownloadProgress := URL_OnDownloadProgress;
     ExecuteTarget(nil) ;
     finally
     free;
end;
 Tdownolad = class(TThread)
 private
     procedure URL_OnDownloadProgress
        (Sender: TDownLoadURL;
         Progress, ProgressMax: Cardinal;
         StatusCode: TURLDownloadStatus;
         StatusText: String; var Cancel: Boolean) ;
 protected
   procedure Execute; override;
 end;

Lecz wyskakują dwa błędy:
[Error] Unit1.pas(46): Incompatible types: 'TComponent' and 'TDownolad' - 3 linijka(with TDownloadURL.Create(self) do),
[Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas',
co jest nie tak?

0

I czego w tych błędach nie rozumiesz?

0

Wiem co one znaczą ale nie umiem ich usunąć

0

TDownloadURL.Create(Application)

0

Pobieranie działa ale jak zrobić aby cancel:=true można było dać np. do buttona?

0

Użyj zmiennej globalnej?

1

ech dzień dziecka:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtActns, StdCtrls, ComCtrls;

type
  TOnProgressEvent = procedure(Sender: TObject; Progress, ProgressMax: Cardinal) of object;

  TThreadDownloader = class(TThread)
  private
    fDownloader: TDownloadURL;
    fCancel: Boolean;
    fProgress, fProgressMax: Cardinal;
    fOnProgressEvent: TOnProgressEvent;

    procedure DoOnProgress;
    procedure OnProgress(Sender: TDownLoadURL; Progress, ProgressMax: Cardinal;
       StatusCode: TURLDownloadStatus; StatusText: String; var Cancel: Boolean);
  protected
    procedure Execute; override;
  public
    constructor Create(Src, Dest: string; Progress: TOnProgressEvent);
    destructor Destroy; override;
    procedure Start;
    procedure Cancel;
  end;

  TForm1 = class(TForm)
    btnStart: TButton;
    btnStop: TButton;
    ProgressBar1: TProgressBar;
    procedure FormCreate(Sender: TObject);
    procedure btnStartClick(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
  private
    { Private declarations }
    fThreadDownloader: TThreadDownloader;
    procedure OnDownloadProgress(Sender: TObject; Progress, ProgressMax: Cardinal);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TThreadDownloader.DoOnProgress;
begin
  if Assigned(fOnProgressEvent) then
    fOnProgressEvent(Self, fProgress, fProgressMax);
end;

procedure TThreadDownloader.OnProgress(Sender: TDownLoadURL; Progress, ProgressMax: Cardinal;
       StatusCode: TURLDownloadStatus; StatusText: String; var Cancel: Boolean);
begin
  Cancel:= fCancel;
  fProgress:= Progress;
  fProgressMax:= ProgressMax;
  Synchronize(DoOnProgress);
end;

procedure TThreadDownloader.Execute;
begin
  fDownloader.ExecuteTarget(nil);
end;

procedure TThreadDownloader.Cancel;
begin
  fCancel:= True;
end;

procedure TThreadDownloader.Start;
begin
  Resume;
end;

constructor TThreadDownloader.Create(Src, Dest: string; Progress: TOnProgressEvent);
begin
  inherited Create(True);
  FreeOnTerminate:= True;
  fCancel:= False;
  fOnProgressEvent:= Progress;
  fDownloader:= TDownloadURL.Create(nil);
  fDownloader.URL:= Src;
  fDownloader.Filename:= Dest;
  fDownloader.OnDownloadProgress:= OnProgress;
end;

destructor TThreadDownloader.Destroy;
begin
  fDownloader.Free;
  inherited Destroy;
end;

//====================== TForm ==========================

procedure TForm1.OnDownloadProgress(Sender: TObject; Progress, ProgressMax: Cardinal);
begin
  ProgressBar1.Max:= ProgressMax;
  ProgressBar1.Position:= Progress;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  fThreadDownloader:= TThreadDownloader.Create('http://cost_tam',  'D:\jakis_plik', OnDownloadProgress);
end;

procedure TForm1.btnStartClick(Sender: TObject);
begin
  fThreadDownloader.Start;
end;

procedure TForm1.btnStopClick(Sender: TObject);
begin
  fThreadDownloader.Cancel;
end;

end.

Oczywiście przydało by się dodać zdarzenia OnBeginDownload i OnEndDownload ale to już twoja działka.

0

Dzięki, kod działa idealnie!

1 użytkowników online, w tym zalogowanych: 0, gości: 1