Ну вот наконец-то я созрел для написании статьи, где я хочу рассказать о том, как можно скачать файл из Интернет без зависания формы, то есть с использованием потоков. Сказать честно, сам в потоках давно разбираюсь так до конца и не разобрался, но маленькую программку по закачке файлов я смог всетаки, наконец-то, написать. Конечно было бы хорошо рассказать немного о потоках Вам, но я в них не силен еще сам, то там что-то прочитал, то там, то там и немного сворганил. Вы наверное замечали, что при скачивании файла из Интернет форма на время этой скачки просто-напросто зависает, что не очень удобно и пользователю ничего нельзя сделать в это время. Если в Indy есть такой замечательный компонент как TidAntiFreeze, то в wininet его совсем нету. Да и то, если у Вас на форме находится TidAntiFreeze, то все равно форма ваша, где происходит скачка немного подвисает, а если у Вас нету в этой время подключения к сети Интернет, то это вообще полный «зависон» формы. Так что тут на это дело приходят потоки.
Как скачать файлы из интернет с помощью wininet, я рассказывал в этой статье. Так, что повторяться уже не буду, мы будем использовать тоже самое, только с помощью потоков это все дело организуем. В Delphi есть класс TThread, специально предназначенный для работы с потоками. Его необходимо описать, что я и сделал, и вот что у меня получилось
type
TMyThread = class(TThread) //Новый класс
private
answer: Integer;
protected
procedure ShowResult;
procedure Execute; override;
end;
Процедура ShowResult - показыват сколько скачало у меня. А процедура Execute - выполняет действия потока. Вот что я написал на процедуру Execute
procedure TMyThread.Execute;
var
session,url:HInternet;
appName:WideString;
BufArr:array[1..1024] of byte;
BufLen:DWORD;
F:File;
begin
answer:=0;
appName:=ExtractFileName(Application.ExeName);
session:=InternetOpen(Pchar(appName),INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);
url:=InternetOpenUrl(session,PAnsiChar('https://belarusy.by/file/videos/src/58346.flv'),nil,0,0,0);
AssignFile(F,'C:\1.flv');
Rewrite(F,1);
repeat
InternetReadFile(url,@BufArr,SizeOf(BufArr),BufLen);
BlockWrite(F,BufArr,BufLen);
answer:=answer+BufLen;
until BufLen=0;
CloseFile(F);
InternetCloseHandle(session);
Synchronize(ShowResult);
end;
То есть все, что и писал в предыдущей статье по скачиванию файлов. Только добавился метод Synchronize(ShowResult), который синхронизирует результат. Далее процедура ShowResult у меня выглядет следующим образом
procedure TMyThread.ShowResult;
begin
Form1.Edit1.Text := IntToStr(answer);
end;
А вот на событие OnClick Button1 я написал следующий код
procedure TForm1.Button1Click(Sender: TObject);
var
MyThread:TMyThread;
begin
MyThread := TMyThread.Create(False);
end;
Мы создаем объект нашего потока, а False означает, что мы начинаем вызывать сразу метод Excecute. В следующей статье я хотел бы рассказать как с помощью потоков, скачать файл используя TIdHTTP.