Вся отрисовка выполняется в главном потоке приложения. Поэтому, если вы пытаетесь выполнить скачивание файла в основном потоке, то вся отрисовка приостановится до момента окончания вашей операции. Поэтому правило хорошего тона - это вынесение долгих операций (загрузка, ответ авторизации и тд) в отдельный поток.
Примерный код приведен ниже:
1. Создаем отдельный поток, в котором вы будите скачивать файл (я поставил для эмуляции скачивания просто паузу на 5 секунд):
type
TMyTask = class (TThread)
protected
FOnTaskStarted: TThreadMethod;
FOnTaskFinished: TThreadMethod;
procedure DoStarted;
procedure DoFinished;
procedure Execute; override;
public
property OnTaskStarted: TThreadMethod read FOnTaskStarted write FOnTaskStarted;
property OnTaskFinished: TThreadMethod read FOnTaskFinished write FOnTaskFinished;
end;
Реализация:
{ TMyTask }
procedure TMyTask.DoFinished;
begin
if Assigned(OnTaskFinished) then
OnTaskFinished;
end;
procedure TMyTask.DoStarted;
begin
if Assigned(OnTaskStarted) then
OnTaskStarted;
end;
procedure TMyTask.Execute;
begin
Synchronize(DoStarted);
try
Sleep(5000); // Эмуляция выполнения 5 Секундной задачи
finally
Synchronize(DoFinished);
end;
end;
Само использование такого потока будет следующим (в моем примере после выполнения операции, появится сообщение):
TForm3 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
FMyTask: TMyTask;
public
procedure DoTaskStarted; // Callback, вызываемый в начале старта операции
procedure DoTaskFinished; // Callback, вызываемый в конце выполнения операции. Аналог OnTerminate
procedure StartMyTask; // Запуск задачи
end;
procedure TForm3.Button1Click(Sender: TObject);
begin
StartMyTask;
end;
procedure TForm3.DoTaskStarted;
begin
end;
procedure TForm3.DoTaskFinished;
begin
ShowMessage('Выполнение задачи окончено');
end;
procedure TForm3.StartMyTask;
begin
if FMyTask <> nil then
begin
FMyTasl.OnTaskStarted := nil;
FMyTasl.OnTaskFinished := nil;
FMyTask.Free;
end;
FMyTask := TMyTask.Create(True);
FMyTask.OnTaskStarted := DoTaskStarted;
FMyTask.OnTaskFinished := DoTaskFinished;
FMyTask.Start;
end;
При таком подходе главный поток не будет блокироваться и будет корректно отрисовываться и работать.