Вверх ↑
Ответов: 4630
Рейтинг: 749
#1: 2017-12-16 15:41:41 ЛС | профиль | цитата
А тут следует знать такое. Сообщения от окон обрабатываются очередью сообщений потока. А как система знает в очередь какого потока направить сообщение? Установлено такое правило: сообщения для окна может получить только тот поток, который создал окно. Следовательно, если какой-то поток создаёт окно, он же должен после этого запустить цикл выборки сообщений из своей очереди до окончания жизни всех созданных им окон. Например, при старте приложения существует только один поток (назовём его главным), в котором и создается первая форма приложения и запускается обработка сообщений этой формы. Если не создавать дополнительных потоков, то в дальнейшем все остальные окна тоже принадлежат главному потоку и их сообщения тоже обрабатывает он.
Компонент Timer основан на сообщениях, поэтому разделяет это поведение. По методу doTimer создаётся системный объект таймера и предполагается, что создавший его поток должен обрабатывать его сообщения. Можно немного пошаманить и убедиться в этом: поставь через хаб после doTimer метод компонента Application.doProcessMessages - этот метод вызывает ту же выборку и обработку сообщений, которая происходит в нашем главном потоке, но поскольку вызывается из параллельного потока, то обрабатываются только сообщения из очереди данного потока.

Предполагаю, так же работает функция MessageBox, показывающая окно из любого потока: она создаёт окно, затем запускает цикл обработки сообщений для этого окна и не возвращает управления, пока окно не закроется.

Существуют некоторые broadcast сообщения (не связанные с окнами), которые попадают во все очереди сообщений.

Есть ещё компонент MMTimer, основанный на параллельном потоке, а не оконных сообщениях, который не подвержен данному поведению. Ну, а чтобы всё-таки включить обычный таймер, нужно метод doTimer вызвать из главного потока, для чего применяется компонент Synchronize.
карма: 26

1
Голосовали:flint2
Редактировалось 2 раз(а), последний 2017-12-18 11:53:17