Este es un viejo problema de Delphi. Cuando se termina la sesión, Windows manda el mesaje WM_ENDSESSION a todas las ventanas de aplicación pero Delphi, al recibir este mensaje, no manda llamar al evento OnClose.
Para interceptar este mensaje, o cualquier otro de Windows, debes crear un manejador del mensaje:
Código:
type
TForm1 = class(TForm)
private
procedure WMEndSession(var Msg: TWMEndSession); message WM_ENDSESSION;
end;
El procedimiento se puede llamar como quieras pero después de la palabra reservada
message especificas el mensaje que deseas interceptar.
Por otro lado, podrías también intentar usar el evento OnCloseQuery en lugar de OnClose ya que éste sí es llamado por Delphi cuando se intenta cerrar la sesión.
De cualquier forma ten en cuenta esto:
En Windows 95/98, cuando se intenta cerrar una sesión, Windows manda primero el mensaje WM_QUERYENDSESSION para preguntar a las aplicaciones si se permite cerrar la aplicación. Si por lo menos una de ellas responde que no, entonces el proceso se interrumpe y la sesión no termina. Si
todas las ventanas aceptan que se cierre la sesión, entonces,
y sólo entonces Windows les manda el mensaje WM_ENDSESSION.
Sin embargo en Windows 2000, y supongo que también en Windows XP, y yendo contra toda lógica, Microsoft cambió la lógica de esto: cuando una ventana responde "sí" al mensaje WM_QUERYENDSESSION Windows le manda
inmediatamente el mensaje WM_ENDSESSION, aún antes de que otras ventanas procesen el mensaje WM_QUERYENDSESSION.
¿En qué te afecta esto?
Bueno, si tu aplicación procesa el mensaje WM_ENDSESSION, guardando los datos que tenga que guardar y cerrándose, y posteriormente otra aplicación contesta "no" a WM_QUERYENSESSION, entonces la sesión no termina pero tu programa sí, lo cual puede no ser lo que deseas.
Hace no mucho tuve un problema similar: requería una aplicación que se ejecutara al comenzar Windows y que no debía terminar sino hasta que terminara la sesión y no podía dejar que terminara por un problema así. La solución que encontré fué la de poner esta línea
SetProcessShutDownParameters($100, 0);
en el OnCreate del formulario principal. Básicamente, la función indica a Windows en qué orden se le debe enviar el mensaje de cerrar sesión. Las aplicaciones en el rango 0-$FF lo reciben al último.
// Saludos