![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Работа со свойствами VCL-компонентов из доп. потоков. [D6, WinME, Win2k, WinXP]
SergP. © (2005-10-04 14:50:00)Делаю сабж. Но не всегда хорошо получается.
Например если меняю кепшен у формы, то он вообще становится пустым пока с окном ничего не сделать ( типа свернуть-развернуть или т.п.)
Если нужно делать сабж, то как правильно поступать?
Переносить в основной поток с помощью PostMessage, или можно попроще?
y-soft (2005-10-05 09:35:00) [1]>SergP. (05.10.05 09:24) [26]
Caption будет меняться в основном потоке, а не в дополнительном...
В дополнительном будет вызываться SendMessage(...
Leonid Troyanovsky (2005-10-05 09:33:00) [2]
> SergP. (05.10.05 09:24) [26]
> > SendMessage(FrmHandle, WM_SETTEXT,..).
> Т.е. мне нужно менять кепшен прямо в дополнительном потокее
> а затем вызывать SendMessage(FrmHandle, WM_SETTEXT,..)?
>
> Я правильно понял?
Нет.
Вторичный поток посылает окну, заголовок которого нужно поменять:
SendMessage(FrmHandle, WM_SETTEXT, 0, LParam(PChar(newCaption)))
И, вообще, RTFM: Synchronize method.
Пока этот материал не будет усвоен хорошо, дальнейшие изыскания
в этом направлении считаю бесполезными.
--
Regards, LVT.
SergP. (2005-10-05 09:24:00) [3]
> Здесь нужен не PostMessage (..WM_USER..), а
> SendMessage(FrmHandle, WM_SETTEXT,..).
Т.е. мне нужно менять кепшен прямо в дополнительном потокее а затем вызывать SendMessage(FrmHandle, WM_SETTEXT,..)?
Я правильно понял?
y-soft (2005-10-05 09:12:00) [4]>Leonid Troyanovsky © (05.10.05 09:09) [24]
Применительно к Caption cогласен, несмотря даже на синхронность вызова, т.к. отрабатывает быстро...
Leonid Troyanovsky (2005-10-05 09:09:00) [5]
> y-soft © (05.10.05 08:14) [23]
> Для сабжевого случая (изменить Caption формы) самым простым
> (и эффективным) будет посылка пользовательского сообщения
> посредством PostMessage
Здесь нужен не PostMessage (..WM_USER..), а
SendMessage(FrmHandle, WM_SETTEXT,..).
Потому как оно:
1. просто
2. эффективно
3. надежно.
--
Regards, LVT.
y-soft (2005-10-05 08:14:00) [6]>SergP. (04.10.05 21:04) [22]
Для сабжевого случая (изменить Caption формы) самым простым (и эффективным) будет посылка пользовательского сообщения посредством PostMessage
Упомянутого "страшного" TWinControl.RecreateWnd можете не боятся, т.к. самопроизвольно он не вызывается :)
Конкретно для формы он вызывается только при изменении следующих свойств:
- BiDiMode;
- BorderStyle;
- Position;
- BorderIcons;
- при Docking'е;
Не изменяйте этих свойств (по крайней мере, пока работает вызывающий поток), тем более, что операция эта "тяжелая" (пересоздаются не только окно самой формы, но и окна всех ее дочерних контролов), и все будет нормально :)
P.S. Сам я пошел по другому пути и написал класс-наследник TThread.
Можете поучаствовать в тестировании, за высказанные замечания буду благодарен...
http://y-soft.comsignal.ru/Delphi/ThreadX_pas.html
SergP. (2005-10-04 21:04:00) [7]
> К тому же кроме PostMessage существует множество других
> способов межпоточного взаимодействия...
Например, что для сабжевого случая можете предложить?
y-soft (2005-10-04 16:36:00) [8]>Leonid Troyanovsky © (04.10.05 16:27) [20]
Ну, цитата слишком объемная получится, поэтому только указание на источник: :)
Часть VI Операции с окнами
Глава 26 Оконные сообщения
Посылка синхронных сообщений окну (в моем экземпляре это стр. 651)
Leonid Troyanovsky (2005-10-04 16:27:00) [9]
> y-soft © (04.10.05 16:10) [15]
> Там, кстати, и освежался... Если помните, то очередь синхронных
Тогда и цитировать надо точней. А "не тормозится очередь",
чего там вовсе не может быть, насколько я помню.
--
Regards, LVT.
y-soft (2005-10-04 16:24:00) [10]>Leonid Troyanovsky © (04.10.05 16:16) [18]
А я разве спорю? Для разных случаев и разные решения. Я только говорю о том, что в большинстве случаев в Delphi Sinchronize используется для тривиальной перерисовки
Кстати, совсем не факт, что надо посылать сообщение непосредственно контролу или форме - хендл Application, например, в приложении не меняется... К тому же кроме PostMessage существует множество других способов межпоточного взаимодействия...
Leonid Troyanovsky (2005-10-04 16:16:00) [11]
> y-soft © (04.10.05 16:02) [10]
> В 99% случаев возвращаемый результат вообще не нужен, зато
> побочные эффекты зачастую вредны...
При использовании SendMessage для синхронизации важен, как раз,
побочный эффект, т.е. то, что внутри обработчика сообщения
можно быть уверенным, что более никакой поток не обратится к тем
ресурсам, которые пользует там первичный (если, конечно, все потоки
дисциплинированны на счет SendMessage).
--
Regards, LVT.
y-soft (2005-10-04 16:15:00) [12]>jack128 © (04.10.05 16:12) [16]
Ну так потому WinAPI и предлагает альтернативы...
А в случае, если только надо послать команду и не дожидаться ответа это чаще всего не имеет такого большого значения, т.к. хендл получателя как правило не запоминают единожды для дальнейшего использования, а получают каждый раз динамически...
jack128 (2005-10-04 16:12:00) [13]y-soft © (04.10.05 16:06) [13]
Для Delphi это к сожалению верно из-за пресловутого RecreateWnd. Но маловероятно
ну это смотря какая у тебя последовательность операторов и о того какие свойства будут меняться у контрола и тд и тп. В некоторых случаях вероятность весьма велика.
Leonid Troyanovsky © (04.10.05 16:02) [11]
да, конечно CM_RECREATEWND имелось в виду..
y-soft (2005-10-04 16:10:00) [14]>Leonid Troyanovsky © (04.10.05 16:08) [14]
Кстати, у потока этих очередей - не одна.
Пора освежиться, у Рихтера.
Там, кстати, и освежался... Если помните, то очередь синхронных сообщений имеет приоритет перед очередью асинхронных...
Leonid Troyanovsky (2005-10-04 16:08:00) [15]
> y-soft © (04.10.05 16:02) [10]
> 2. Тормозится очередь сообщений вызываемого потока
Очередь - это всего лишь некая структура, она, скажем,
кхм.. статичная.
Кстати, у потока этих очередей - не одна.
Пора освежиться, у Рихтера.
--
Regards, LVT.
y-soft (2005-10-04 16:06:00) [16]>jack128 © (04.10.05 16:01) [9]
хендл WinControl'а имеет свойство меняться
Для Delphi это к сожалению верно из-за пресловутого RecreateWnd. Но маловероятно
jack128 (2005-10-04 16:03:00) [17]begin...end © (04.10.05 15:57) [8]
Хэндл можно передавать потоку как параметр его функции. Разве нет?
Можно. Но хендл WinControl'а имеет свойство меняться..
Leonid Troyanovsky (2005-10-04 16:02:00) [18]
> begin...end © (04.10.05 15:57) [8]
> > о самом обычном. О свойстве TWinControl.Handle
> Хэндл можно передавать потоку как параметр его функции.
Возможно, что имелась ввиду возможное RecreateWnd.
--
Regards, LVT.
y-soft (2005-10-04 16:02:00) [19]>jack128 © (04.10.05 15:55) [7]
К тому же нужно иметь в виду, что иногда эти сообщения вообще могут не дойти до адресата
Причина использования синхронных вызовов совсем иная - они гарантируют получение вызывающим потоком результата вызова и не более того. Зато привносят побочные эффекты - на время выполнения синхронного вызова:
1. Тормозится вызывающий поток
2. Тормозится очередь сообщений вызываемого потока
3. Тормозятся все потоки, которые послали вызываемому потоку синхронный выхов чуть позже вызывающего потока
В 99% случаев возвращаемый результат вообще не нужен, зато побочные эффекты зачастую вредны...
Так что исключительное использование синхронных вызовов не более чем предрассудок...
P.S. Вы все-таки гляньте в исходники TThread, как он реализован в D7, и сравните с реализацией в ранних версиях Delphi...
jack128 (2005-10-04 16:01:00) [20]begin...end © (04.10.05 15:57) [8]
Хэндл можно передавать потоку как параметр его функции. Разве нет?
Можно. Но хендл WinControl'а имеет свойство меняться..