frogb
frogb

Reputation: 2060

What might cause a Delphi program to 'prevent Windows shutdown'?

One of my Delphi XE2 programs, when running and idle, 'prevents Windows shutdown'. This is not the case with most of my applications and I need to resolve it. On XP, Windows silently fails to close; on Win7 the dialog shows my application preventing shutdown.

Unlike the similar questions here, the program is single-threaded, I am not using the tray, and I have temporarily disconnected the OnCloseQuery and FormClose events in the main form and the one subsidiary form that had them. In normal use the program closes cleanly and no trace of it remains in Process Explorer.

I have experimemtally added WM_QueryEndSession and WM_EndSession handlers which write a log message to the Windows Event log. On a test Windows shutdown, only the former fires, with Wparam and Lparam both zero.

I would be most grateful for any ideas on what could be causing this, or for how to investigate it further. I am reluctant to try a call to Halt on the WM_QueryEndSession without knowing what is going on.

Upvotes: 0

Views: 680

Answers (1)

frogb
frogb

Reputation: 2060

In the final state where it was failing, the program had the FormCloseQuery methods reconnected, but in each one it was now checking a 'shuttingdown' global boolean, and allowing close if this was set. Shuttingdown was set to true in a WM_QUERYENDSESSION message handler on the main form. This works for single-form applications.

The problem was caused by the fact that the FormCloseQuery handlers for other than the main form are all called before the WM_QUERYENDSESSION message handler on the main form. I had missed this fact in the various edits and tests that I had been making.

If your application has any subsidiary form which has a FormCloseQuery handler, in which the result might be 'do not close' if it is called at a random moment (e.g. at end session, when the form might not have been initialized) then you require a WM_QUERYENDSESSION message handler in each such form. This can then set a form or local variable to cause FormCloseQuery to set canclose to true.

Upvotes: 1

Related Questions