Собственно была программа на D7, ввиду запутанности кода и в связи с переходом на XE4 решил переписать с нуля.
В частности, из главного окна, в цикле запускаются потоки, в потоке IdHTTP проверяет наличие файла и возвращает строку в зависимости от ответа.
Когда наследник TThread описан в модуле главного окна все просто
Код:
...
Synchronize(WriteRespons);
end;
procedure TDownload.WriteRespons;
begin Form1.Memo1.Lines.Append(ResStr);
Form1.ProgressBar2.Position:= trcount;
{и т.д.}
а как быть если поток описан в другом модуле?
Вроде бы вариант - посылка сообщения, но в сообщении нельзя передать строку, можно передать указатель, а с указателями для меня не все ясно.
Где-то наткнулся на идею обработать OnTerminate
Код:
unit MyThreads;
...
type
TMyThread = class(TThread)
...
public
property Str: string read FStr write FStr;
end;
unit Unit1;
...
var
Form1: TForm1;
thr: TMyThread;
...
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
ListBox1.Clear;
for i := 0 to 12 do
begin
thr:= TMyThread.Create(True);
thr.FreeOnTerminate:= True;
thr.OnTerminate:= Form1.MyProc;
thr.Start;
end;
end;
procedure TForm1.MyProc(Sender: TObject);
begin
ListBox1.Items.Append('Str - '+thr.Str);
end;
Но мне кажется это плохая идея, с одной стороны мне не нужно получать данные от потока в процессе его работы, только результат по его завершении. С другой, как я понимаю, здесь нет синхронизации и будут проблемы с доступом. К тому же переменную потока придется объявлять как глобальную, а это не гут.
Вообще в Дельфи стандартно и создается отдельный модуль (New>Other>Thread Object) и в заготовке модуля в комментарии говорится о необходимости использования Synchronize, значит есть какой то способ обмена данными. А во всех статьях "Потоки для чайников" пишут - " ... для простоты опишем новый класс в главном модуле ...", хоть кто-нибудь привел бы пример с отдельным unit-ом.
Похоже я как всегда упускаю что-то до такой степени очевидное, что об этом ни кто не пишет.