Что может заставить программу на Delphi "предотвратить завершение работы Windows"?
Одна из моих программ на Delphi XE2 во время работы и простоя "предотвращает завершение работы Windows". Это не относится к большинству моих приложений, и мне нужно решить их. На XP Windows молча не удается закрыть; на Win7 диалог показывает мое приложение, предотвращающее выключение.
В отличие от подобных вопросов здесь, программа является однопоточной, я не использую трей, и я временно отключил события OnCloseQuery и FormClose в основной форме и в одной вспомогательной форме, в которой они были. При обычном использовании программа закрывается чисто, и в Process Explorer ее не остается.
Я экспериментально добавил обработчики WM_QueryEndSession и WM_EndSession, которые записывают сообщение в журнал событий Windows. При тестовом завершении работы Windows срабатывает только первый, с Wparam и Lparam оба равны нулю.
Я был бы очень признателен за любые идеи о том, что может быть причиной этого, или за то, как исследовать это дальше. Я неохотно пытаюсь вызвать Halt на WM_QueryEndSession, не зная, что происходит.
1 ответ
В конечном состоянии, в котором произошел сбой, программа повторно подключила методы FormCloseQuery, но в каждом из них она теперь проверяла глобальное логическое значение "shutdowndown" и разрешала закрытие, если это было установлено. Завершение работы было установлено в true в обработчике сообщений WM_QUERYENDSESSION в главной форме. Это работает для приложений с одной формой.
Проблема была вызвана тем фактом, что все обработчики FormCloseQuery, отличные от основной формы, вызываются до обработчика сообщений WM_QUERYENDSESSION в главной форме. Я упустил этот факт из различных правок и тестов, которые я делал.
Если в вашем приложении есть какая-либо вспомогательная форма, имеющая обработчик FormCloseQuery, в котором результат может быть "не закрываться", если он вызывается в произвольный момент (например, в конце сеанса, когда форма могла не инициализироваться), тогда вам требуется обработчик сообщений WM_QUERYENDSESSION в каждой такой форме. Затем можно установить форму или локальную переменную, чтобы FormCloseQuery установил для canclose значение true.