![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Обращение из потока [D7]
ixen © (2012-03-20 10:30:00)Привет! Пишу поток в отдельном модуле. Можно ли в create потока обращаться к свойствам главной формы? В Execute использую synchronize, как положено. Спасибо!
Сергей М. (2012-03-20 14:55:00) [1]деструктор к этому механизму не имеет отношения
ixen (2012-03-20 14:04:00) [2]
> Достаточно назначить обработчик события OnTerminate
я хотел так сделать, но не нашел пример описания деструктора потока, поэтому пока оставил так..
Сергей М. (2012-03-20 14:01:00) [3]
> synchronize я использую в Execute только в куске завершения
> потока
Лишние телодвижения.
Достаточно назначить обработчик события OnTerminate - он автоматически будет вызван в контексте осн.потока после штатного (не вызвавшего исключение) завершения метода Execute.
Ega23 (2012-03-20 12:06:00) [4]Ну это ничего.
А то повеяло Призраком Архангельского.
ixen (2012-03-20 11:13:00) [5]
> На душе стало немножечко тревожно.
> Покажи, как ты используешь synchronize
>
>
Если честно то synchronize я использую в Execute только в куске завершения потока:
try
.
.
.
finally
.
.
Synchronize(delThread);
.
.
end;
procedure TMyThread.DelThread;
begin
Fmain.ThreadList.Remove(self);
end;
В основном использую SendMessage.
ixen (2012-03-20 11:09:00) [6]Спасибо, буду пробовать!!
Ega23 (2012-03-20 11:09:00) [7]
> В Execute использую synchronize, как положено.
На душе стало немножечко тревожно.
Покажи, как ты используешь synchronize
Dimka Maslov (2012-03-20 11:04:00) [8]Про Resume я погорячился...
Можно сделать ещё так: в TMainForm.WMThreadListAdd задать все требуемые параметры потока, и там же ему сделать Resume.
Dimka Maslov (2012-03-20 10:50:00) [9]Если оно так, то надо учитывать, что Handle любого контрола может по ходу действия поменяться. Здесь лучше всего объявить своё сообщение
const
WM_THREADLIST_ADD = WM_USER + $100;
type
TMainForm = class(TForm)
private
....
procedure WMThreadListAdd(var Message: TMessage); message WM_THREADLIST_ADD;
...
end;
procedure TMainForm.WMThreadListAdd(var Message: TMessage);
begin
ThreadList.Add(TThread(Message.lParam));
end;
constructor TMyThread.Create;
begin
.....
PostMessage(Application.MainForm.Handle, WM_THREADLIST_ADD, 0, LPARAM(Self));
// Resume не надо, активируется само
end;
И каждый раз, когда нужна форма, обращаться через Application.MainForm.Handle через SendMessage, в этом случае синхронизация будет сделана автоматически.
ixen (2012-03-20 10:46:00) [10]В мой программе потоки создаются только основным потоком, поэтому путаницы откуда создался поток не будет.
Я так и делал, передавал параметры в конструктор в явном виде
TMyThread.Create(const adam_id:Integer; MH:HWND);, но параметров стало многовато и стало все громоздко, вотя и подумал было бы проще обращаться к ним напрямую из потока.
Dimka Maslov (2012-03-20 10:41:00) [11]Конструктор потока выполняется в контексте вызывающего его потока, следовательно, если это основной поток, то можно. Но если это другой поток, то нельзя. Чтобы потом не выяснять, откуда создаётся новый поток, лучше все данные, которые в конструкторе берутся с главной формы, передавать в него в явном виде, для чего надо создать ещё один конструктор со всеми параметрами.
ixen (2012-03-20 10:40:00) [12]Дополню, ясности примером:
constructor TMyThread.Create(const adam_id:Integer; MH:HWND);
var i:Integer;
begin
inherited Create(True); // Вызов конструктора родительского класса
FreeOnTerminate:=True;
priority:=tpLower;
Fmain.ThreadList.Add(self);
main_HW:=Fmain.Handle;
Resume; // Переводим поток в состояние "активный"
end;
Можно ли так делать, если обращение к главной форме идет до активации потока?