Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
23-10-2007 15:58
Но все же интересно, как в сервисе который не создает никаких окон
А вы уверены что никаких? Я вот например вижу в вашем mSimpleTCP2 функцию AllocateHWnd и даже попытку обработать WM_QUERYENDSESSION.
22-10-2007 02:17 | Комментарий к предыдущим ответам
Да, здесь вы правы, видимо это действительно будет бесполезно, если только не нужна какая то спецобработка этого события. Кстати, на форме то обработчик WM_QUERYENDSESSION есть, и он обращается к FormCloseQuery. Вобщем, что то мы несколько уклонились от темы вопроса... Хотя другие проблемы, связанные с незавершением работы системы мне тоже не известны.
21-10-2007 06:08 | Комментарий к предыдущим ответам
Для наследников TWinControl имеет смысл первый код
Нет не имеет, потому как оконная процедура по умолчанию и так вернёт единицу. Хуже от вашего кода конечно не будет, но к чему лишние телодвижения? Вообще это классический пример "шаманства"... вопросы про WM_QUERYENDSESSION возникают постоянно и наиболее частый ответ "пишите обработчик, возвращайте единицу", при этом почему-то забывают, что WM_QUERYENDSESSION посылается всем toplevel окнам, но обработчик почему-то надо сделать именно на форме, хотя проблема на самом деле связана с неправильным написанием WndProc при использовании AllocateHWnd (или любом другом способе создания не VCL окна). И кстати говоря это может быть не единственной (хотя других я честно говоря не знаю) проблемой, если глотать необрабатываемые сообщения в WndProc.
PS: Я не проверял, но помоему дочерним окнам WM_QUERYENDSESSION не посылается, так что создание обработчика "В компоненте (с имеющейся оконной процедурой)", совсем уж странно: он просто никогда не будет вызван.
После таких действий компонент не будет препятствовать завершению работы приложения (сервиса).
Всё таки более правильно вызывать DefWindowProc для всех необработанных сообщений, что собственно и делается в TWinControl.DefaultHandler, так что для наследников TWinControl ваш код смысла не имеет, это актуально только для окон созданных с помощью AllocateHWnd.
procedure TSomeComponent.WndProc(var Mesaga: TMessage);
begin
...
case (Mesaga.Msg) of
...
WM_QUERYENDSESSION: begin
Mesaga.Result := 1;
end;
...
end;
...
end;
После таких действий компонент не будет препятствовать завершению работы приложения (сервиса).
В принципе Kisius прав, если сервис интерактивный и создаёт какую нибудь "иконку в трее" (что типично для таких сервисов), то неправильная обработка WM_QUERYENDSESSION (это беда многих "иконок в трее") может быть причиной проблемы.
Как я понимаю сервис интерактивный... т.е. взаимодейтсвует с рабочим столом. Когда Windows завершает работу, она посылает окнам сообщение WM_QUERYENDSESSION. Скорее всего проблема в том, что какая то форма, например, или компонент на форме не дают остановить сервис из-за того, что не обрабатывают это сообщение или при обработке возвращают отрицательный результат. Например, на форме в обработчике FormCloseQuery в момент опроса параметр CanClose может быть выставлен в False.
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.