Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизОбращение из потока Найти похожие ветки
← →
ixen (2012-03-20 10:30) [0]Привет! Пишу поток в отдельном модуле. Можно ли в create потока обращаться к свойствам главной формы? В Execute использую synchronize, как положено. Спасибо!
← →
ixen (2012-03-20 10:40) [1]Дополню, ясности примером:
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;
Можно ли так делать, если обращение к главной форме идет до активации потока?
← →
Dimka Maslov © (2012-03-20 10:41) [2]Конструктор потока выполняется в контексте вызывающего его потока, следовательно, если это основной поток, то можно. Но если это другой поток, то нельзя. Чтобы потом не выяснять, откуда создаётся новый поток, лучше все данные, которые в конструкторе берутся с главной формы, передавать в него в явном виде, для чего надо создать ещё один конструктор со всеми параметрами.
← →
ixen (2012-03-20 10:46) [3]В мой программе потоки создаются только основным потоком, поэтому путаницы откуда создался поток не будет.
Я так и делал, передавал параметры в конструктор в явном видеTMyThread.Create(const adam_id:Integer; MH:HWND);
, но параметров стало многовато и стало все громоздко, вотя и подумал было бы проще обращаться к ним напрямую из потока.
← →
Dimka Maslov © (2012-03-20 10:50) [4]Если оно так, то надо учитывать, что 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, в этом случае синхронизация будет сделана автоматически.
← →
Dimka Maslov © (2012-03-20 11:04) [5]Про Resume я погорячился...
Можно сделать ещё так: в TMainForm.WMThreadListAdd задать все требуемые параметры потока, и там же ему сделать Resume.
← →
ixen (2012-03-20 11:09) [6]Спасибо, буду пробовать!!
← →
Ega23 © (2012-03-20 11:09) [7]
> В Execute использую synchronize, как положено.
На душе стало немножечко тревожно.
Покажи, как ты используешь synchronize
← →
ixen (2012-03-20 11:13) [8]
> На душе стало немножечко тревожно.
> Покажи, как ты используешь synchronize
>
>
Если честно то synchronize я использую в Execute только в куске завершения потока:
try
.
.
.
finally
.
.
Synchronize(delThread);
.
.
end;
procedure TMyThread.DelThread;
begin
Fmain.ThreadList.Remove(self);
end;
В основном использую SendMessage.
← →
Ega23 © (2012-03-20 12:06) [9]Ну это ничего.
А то повеяло Призраком Архангельского.
← →
Сергей М. © (2012-03-20 14:01) [10]
> synchronize я использую в Execute только в куске завершения
> потока
Лишние телодвижения.
Достаточно назначить обработчик события OnTerminate - он автоматически будет вызван в контексте осн.потока после штатного (не вызвавшего исключение) завершения метода Execute.
← →
ixen (2012-03-20 14:04) [11]
> Достаточно назначить обработчик события OnTerminate
я хотел так сделать, но не нашел пример описания деструктора потока, поэтому пока оставил так..
← →
Сергей М. © (2012-03-20 14:55) [12]деструктор к этому механизму не имеет отношения
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.057 c