|
Вопрос # 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;
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|