Ver Mensaje Individual
  #2  
Antiguo 26-02-2004
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Reputación: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
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
Responder Con Cita