| 
| 
 | Вопрос # 3 423/ вопрос открыт / | 
 |  Здравствуйте, уважаемые эксперты!Подскажите, пожалуйста, как можно выполнить этот код в отдельном потоке?
 Приложение:Переключить в обычный режим     unit Unit1; interface uses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  Dialogs, StdCtrls,URLMon; type  TForm1 = class(TForm)    Button1: TButton;    procedure Button1Click(Sender: TObject);  private    { Private declarations }  public    { Public declarations }  end; var  Form1: TForm1; implementation {$R *.dfm}function DownloadFile(SourceFile, DestFile: string): Boolean;begin  try    Result := UrlDownloadToFile(nil, PChar(SourceFile), PChar(DestFile), 0, nil) = 0;  except    Result := False;  end;end;  procedure TForm1.Button1Click(Sender: TObject);const   SourceFile =
'http://downloads.kaspersky-labs.com/trial/registered/8NGILSWTCHAPVSJ1NTX8/kav9.0.0.736ru.exe ';   DestFile = 'c:kav9.0.0.736ru.exe ';begin  if DownloadFile(SourceFile, DestFile) then  begin   end  else end;
|  |   Вопрос задал: Kyran29 (статус: Посетитель)Вопрос отправлен: 20 ноября 2009, 12:14
 Состояние вопроса: открыт, ответов: 2.
 |  Ответ #1. Отвечает эксперт: DNK Здравствуйте, Kyran29!Это элементарно. К компилятору не ходи.
 Приложение:Переключить в обычный режим type  TForm1 = class(TForm)    Button1: TButton;    procedure Button1Click(Sender: TObject);  private    { Private declarations }  public    { Public declarations }  end;   TLoadThread = class(TThread)  protected    procedure Execute; override;  end;  var  Form1: TForm1; implementation {$R *.dfm} function DownloadFile(SourceFile, DestFile: string): Boolean;begin  try    Result := UrlDownloadToFile(nil, PChar(SourceFile), PChar(DestFile), 0, nil) = 0;  except    Result := False;  end;end; procedure TForm1.Button1Click(Sender: TObject);begin  TLoadThread.Create(False);end; procedure TLoadThread.Execute;const   SourceFile =
'http://downloads.kaspersky-labs.com/trial/registered/8NGILSWTCHAPVSJ1NTX8/kav9.0.0.736ru.exe ';   DestFile = 'c:kav9.0.0.736ru.exe ';begin  if DownloadFile(SourceFile, DestFile) then  begin   end  else end;
|  | Ответ отправил: DNK (статус: Студент)Время отправки: 20 ноября 2009, 14:26
 Оценка за ответ: 3
 |  Ответ #2. Отвечает эксперт: Паровоз Здравствуйте, Kyran29!
 Делать как предлагает Ершов Денис нельзя. Методы VCL из вторичного потока можно вызывать только через Synchronize. Для этого нужно расширить класс TLoadThread:
 
 TLoadThread = class(TThread)
protected
  FResult:String;
  procedure Execute; override;
  procedure ShowResult;
end;Изменить метод Execute: 
 procedure TLoadThread.Execute;
const
  SourceFile = 'http://downloads.kaspersky-labs.com/trial/registered/8NGILSWTCHAPVSJ1NTX8/kav9.0.0.736ru.exe ';
  DestFile = 'c:\kav9.0.0.736ru.exe ';
begin
  if DownloadFile(SourceFile, DestFile) then
    FResult:=''Файл загружен!'
  else
    FResult:=''Ошибка при загрузке - '+ SourceFile;
    Synchronize(ShowResult);
end;
 
procedure TLoadThread.ShowResult;
begin
  ShowMessage(FResult);
end;
|  | Ответ отправил: Паровоз (статус: 10-ый класс)Время отправки: 20 ноября 2009, 15:15
 Оценка за ответ: 5
 |  
 Мини-форум вопросаВсего сообщений: 10; последнее сообщение — 27 ноября 2009, 10:22; участников в обсуждении: 4. 
|   | Вадим К (статус: Академик), 20 ноября 2009, 12:28 [#1]:А почему вы не смотрите те примеры, которые я раньше приводил??? там есть работа в потоке Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Паровоз (статус: 10-ый класс), 20 ноября 2009, 15:21 [#2]:P.S. Двойные кавычкми нужно заменить на одинарные: FResult:='Файл загружен!'
 FResult:='Ошибка при загрузке - '+ SourceFile
 |  
|   | Вадим К (статус: Академик), 20 ноября 2009, 15:37 [#3]:Что то мне подсказывает, что оба приведённых кода не будут работать правильно. Скажите честно, кто тестировал код перед отправкой? Галочка "подтверждения прочтения" - вселенское зло. |  
|   | DNK (статус: Студент), 20 ноября 2009, 16:35 [#4]:Только не я.  Но код точно должен выполниться.
 "Digital Networked Knight" |  
|   | Вадим К (статус: Академик), 20 ноября 2009, 16:43 [#5]:То, что код выполняется в главном треде, абсолютно не означает, что он должен выполняться в другом. тем более, многие ли знают, что в этом коде неявно подгружается половина ядра Internet Explorer? Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Паровоз (статус: 10-ый класс), 20 ноября 2009, 20:07 [#6]:1)Собственно говря нужно позаботиться об отсутствии утечек и Button1Click заменить на что-нибудь более правильное, типа procedure TForm1.Button1Click(Sender: TObject);
 var
 lt:TLoadThread;
 begin
 lt:=TLoadThread.Create(False);
 lt.FreeOnTerminate:=True;
 lt.Resume;
 end;
 2) вызов ShowMessage без Synchronize, конечно, недопустим.
 3) код на всякий случай протестировал - выполняется и файл загружается. Не вижу причин для беспокойства.
 |  
|   | Kyran29 (статус: Посетитель), 22 ноября 2009, 01:24 [#7]:Здравствуйте, Паровоз! Подскажите пожалуйста, как теперь отразить весь процесс закачки файла, с помощью компонентов TProgressBar и TLabel.
 |  
|   | Паровоз (статус: 10-ый класс), 24 ноября 2009, 23:26 [#8]:В этом случае нужно использовать последний параметр функции UrlDownloadToFile - интерфейс IBindStatusCallBack. Создаете класс, реализующий этот интерфейс. Достаточно реализовать только одну функцию OnProgress, а все остальные можно сделать заглушками. При обработке ulStatusCode вычиcляете позицию newPos для TProgressBar как то так: 
 if ulStatusCode=BINDSTATUS_ENDDOWNLOADDATA then newPos:=100
else if ulProgressMax=0 then newPos:=0
     else newPos:=((ulProgress*100) div ulProgressMax);Соответственно управляете и текстом TLabel. Если, например, оказывается, что ulStatusCode=BINDSTATUS_DOWNLOADINGDATA, то пишите в TLabel 'Загрузка...'. |  
|   | Kyran29 (статус: Посетитель), 27 ноября 2009, 07:17 [#9]:P.S Здравствует Паровоз !
 На форме имеется кнопка «Отменить закачку файла» подскажите, пожалуйста, как создать событие, которое завершает работу потока.
 |  
|   | Паровоз (статус: 10-ый класс), 27 ноября 2009, 10:22 [#10]:В классе, который реализует интерфейс IBindStatusCallBack вводите дополнительное поле, например, FAbort типа Boolean. Предположим, что obj - это созданный Вами для управления загрузкой экземпляр этого класса. Тогда в обработчике кнопки завершения пишите obj.FAbort:=True. Кроме того, в реализации метода OnProgress вставляете код проверки: 
 if FAbort then
begin
  FAbort:=False;
  Result:=E_ABORT;
  Exit;
end; |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |