Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не могу обработать сообщение WM_USER 
V
    Опции темы
Gnus
Дата 11.11.2011, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 22.11.2010
Где: СПб

Репутация: нет
Всего: нет



Доброго времени суток.
Суть проблемы такова: есть объект, который порождает нить. Нить без освобождения при завершении. Завершение нити может произойти при разрушении родителя, тогда нить тоже разрушается. Но возможны ситуации, когда завершение нити произошло в ходе ее исполнения. Необходимо проинформировать родителя о завершении нити и инициировать его (родителя) разрушение.

Попытка решения с помощью сообщений: перед завершением нити вызывается метод родителя, в котором вызывается метод PostMessage(0, WM_USER, 0, 0), которая возвращает истину. У родителя описан следующий метод обработки сообщения WM_USER:

Код

procedure WMUser(var Msg:TMessage); message WM_USER;


в реализации WMUser пока что только контрольная печать в файл.

Вобщем, не вызывается этот WMUser. Уже и не знаю, что делать.
PM   Вверх
kami
Дата 11.11.2011, 20:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(Gnus @  11.11.2011,  13:40 Найти цитируемый пост)
PostMessage(0, WM_USER, 0, 0)

Первый параметр функции, конечно, просто так придуман...
Это намек. Остальное скажут F1 и MSDN
PM MAIL WWW   Вверх
Gnus
Дата 11.11.2011, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 22.11.2010
Где: СПб

Репутация: нет
Всего: нет



Цитата(kami @  11.11.2011,  20:44 Найти цитируемый пост)
Первый параметр функции, конечно, просто так придуман...
Это намек. Остальное скажут F1 и MSDN 

Экий толстый намёк.
Упомянутый F1 не запрещает вызывать PostMessage, передавая первым параметром ноль. В этом случае вызов PostMessage аналогичен вызову PostThreadMessage с передачей идентификатора текущего потока.


PM   Вверх
kami
Дата 12.11.2011, 09:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(Gnus @  11.11.2011,  22:33 Найти цитируемый пост)
 F1 не запрещает вызывать PostMessage

Попробовал бы он запретить smile
Только не надо забывать про 
Цитата(Gnus @  11.11.2011,  22:33 Найти цитируемый пост)
с передачей идентификатора текущего потока

Метод, содержащий PostMessage, вызывается в контексте порожденной нити (судя по описанию). То, что этот метод содержится не в самом коде потока, а в коде родителя. ничего не меняет. Куда отправится сообщение? Ждут ли его там, куда оно в действительности улетело?
PM MAIL WWW   Вверх
Gnus
Дата 12.11.2011, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 22.11.2010
Где: СПб

Репутация: нет
Всего: нет



Цитата(kami @  12.11.2011,  09:40 Найти цитируемый пост)
Куда отправится сообщение? Ждут ли его там, куда оно в действительности улетело? 

но разве эта процедура в коде родителя 
Цитата(Gnus @  11.11.2011,  13:40 Найти цитируемый пост)
procedure WMUser(var Msg:TMessage); message WM_USER;

не является обработчиком события?

Попробовал перекрыть DefaultHandler родителя - не выполняется.
Событие OnTerminate у потока тоже не выполняется.
Какой-то замкнутый круг.
Повторюсь: Родитель (наследник TObject) порождает нить (наследник TThread). При завершении нити необходимо разрушить родителя. Что посоветуете?

Это сообщение отредактировал(а) Gnus - 12.11.2011, 10:12
PM   Вверх
kami
Дата 12.11.2011, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Еще раз повторяю:
PostMessage будет вызвано в контексте созданного потока. Это значит, что сообщение (при параметре Handle = 0) будет отправлено именно этому созданному потоку. А там оно не нужно. Потому что в этом случае сообщение нужно отправлять не потоку, а требуемому окну. И скорее всего у этого потока даже выборка сообщений не реализована.


Цитата(Gnus @  12.11.2011,  09:47 Найти цитируемый пост)
не является обработчиком события?

Я не знаю, что это за компонент-родитель. Может, и не является, если родитель - не оконный. В любом случае, сообщение до него не доходит.

Это сообщение отредактировал(а) kami - 12.11.2011, 11:35
PM MAIL WWW   Вверх
Gnus
Дата 12.11.2011, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 22.11.2010
Где: СПб

Репутация: нет
Всего: нет



Т.е., насколько я понял, использовать механизм сообщений нельзя. Никакого "требуемого окна" у меня нет.
Как же организовать отложенное уведомление родителя о завершении потока?

Это сообщение отредактировал(а) Gnus - 12.11.2011, 11:51
PM   Вверх
kami
Дата 12.11.2011, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(Gnus @  12.11.2011,  11:48 Найти цитируемый пост)
использовать механизм сообщений нельзя

Я этого не говорил.
Цитата(Gnus @  12.11.2011,  11:48 Найти цитируемый пост)
Никакого "требуемого окна" у меня нет.

Если  нет - не проблема создать.
Что представляет из себя родитель? Что за класс (если собственный - наследник какого базового)?

PM MAIL WWW   Вверх
Gnus
Дата 12.11.2011, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 22.11.2010
Где: СПб

Репутация: нет
Всего: нет



Цитата(kami @  12.11.2011,  11:55 Найти цитируемый пост)
Что представляет из себя родитель? Что за класс (если собственный - наследник какого базового)?


Цитата(Gnus @  12.11.2011,  09:47 Найти цитируемый пост)
Повторюсь: Родитель (наследник TObject) порождает нить (наследник TThread). При завершении нити необходимо разрушить родителя.


PM   Вверх
kami
Дата 12.11.2011, 12:41 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(Gnus @  12.11.2011,  12:02 Найти цитируемый пост)
Родитель (наследник TObject)

Это не страшно.
Принцип работы следующий (код будет отрывками, только концепция, возможно несколько ошибок, т.к. пишу прямо в браузере):
1. Объявляем приватную переменную myHandle:THandle и оконную процедуру myMsgHandler(var Message: TMessage)
2. В конструкторе объекта (надеюсь, этот объект создается в главном потоке?) пишем:
  
Код

myHandle:=AllocateHWND(myMsgHandler)

3. Создаваемому потоку передаем этот myHandle. Где он будет храниться - определите сами.
4. в процедуре myMsgHandler пишем следующее:
Код

  if Message.msg = WM_USER then
    begin
      // здесь - код, обрабатывающий уничтожение или_что_там_еще вторичного потока.
    end
  else
    Message.Result:=DefaultWindowProc(myHandle, Message.Msg, Message.WParam, Message.LParam); // может, название процедуры написал неверно.
    // возможно, она называется DefWindowProc или как-нибудь так.

5. При необходимости передачи сообщения в методе вторичного потока пишем PostMessage(ParentHandle, WM_User.....). И не нужно вызывать методы родителя, прямо в коде вторичного потока, он же из п.2 знает хендл нужного окна.

Добавлено через 1 минуту и 57 секунд
Обратите внимание на 
Цитата(kami @  12.11.2011,  12:41 Найти цитируемый пост)
надеюсь, этот объект создается в главном потоке?

В противном случае манипуляции могут резко поменяться или дополниться.

Это сообщение отредактировал(а) kami - 12.11.2011, 12:41
PM MAIL WWW   Вверх
Gnus
Дата 12.11.2011, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 22.11.2010
Где: СПб

Репутация: нет
Всего: нет



kami, огромное спасибо. Признаюсь, не знал, что можно привязать к обычному объекту окно с функцией обработки сообщений. До сегодняшнего дня не задумывался о том, как работает тот же TTimer например. Так что еще раз спасибо за AllocateHWND.

Кстати, в деструкторе родителя приходится делать DeallocateHWND.

Если под главным потоком Вы имели ввиду поток VCL, то тогда ответ отрицательный. Объект-родитель создается другими объектами при вызове главным потоком функции подключения из dll. Соответственно, в списке потоков я вижу их один после запуска приложения, три после вызова функции подключения из dll. После неудачи подключения теперь остается только один поток, как я и хотел.


PM   Вверх
kami
Дата 12.11.2011, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(Gnus @  12.11.2011,  13:30 Найти цитируемый пост)
стати, в деструкторе родителя приходится делать DeallocateHWND.

Я рад, что Вы не ограничились только воспроизведением моего совета.  smile 

Цитата(Gnus @  12.11.2011,  13:30 Найти цитируемый пост)
Объект-родитель создается другими объектами при вызове главным потоком функции подключения из dll. Соответственно, в списке потоков я вижу их один после запуска приложения, три после вызова функции подключения из dll.

Это (дальше - 2 варианта):
а) ничего не значит, потому что несмотря на создание других потоков, объект создается в контексте основного (да, я говорил именно проVCL-поток). В этом случае всё отлично, потому что vcl поток имеет обработчик сообщений.
б) если объект создается в дополнительном потоке и всё работает, значит этот дополнительный поток создал и имеет очередь сообщений, ну и обрабатывает их, само собой. Если бы поток не имел цикл обработки сообщений, то ни одно окно, созданное в его контексте (в т.ч. и созданное AllocateHWND) ничего бы не получало.

Это сообщение отредактировал(а) kami - 12.11.2011, 14:04
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0503 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.