Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   API de Windows (https://www.clubdelphi.com/foros/forumdisplay.php?f=7)
-   -   Cerrar aplicación al apagar el sistema (https://www.clubdelphi.com/foros/showthread.php?t=27523)

MDSato 23-11-2005 13:26:49

Cerrar aplicación al apagar el sistema
 
Estimados colegas,

Tengo un problema con el apagado del sistema y la aplicación que desarrollo. Lo que me gustaría conseguir es que cuando apaguen el sistema (esto es, CERRAR SESION, APAGAR EL SISTEMA o REINICIAR) mi aplicación se cerrara automáticamente.

He aplicado dos soluciones descritas en este foro. Una la de Roman (http://www.clubdelphi.com/foros/show...60&postcount=2) redefiniendo los mensajes de este modo:

Código Delphi [-]
procedure TFormMainImpre.WMQueryEndSession (var Msg : TWMQueryEndSession);
begin
     Msg.Result := 1;
end;
 
procedure TFormMainImpre.WMEndSession (var Msg : TWMEndSession);
begin
     Msg.EndSession := True;
     Msg.Result := 1;
     Close;
     inherited;
end;

y también he probado con la solución descrita aquí: http://www.delphifaq.com/faq/delphi/vcl/f285.shtml

Con las dos alternativas consigo lo mismo... Efectivamente mi aplicación se cierra correctamente. El problema es que por algún motivo, detiene el apagado de Windows que se ha solicitado, y por tanto el ordenador continua encendido (aunque con mi aplicación cerrada). ¿Alguien podría darme alguna orientación al respecto?
Muchas gracias por adelantado.

vtdeleon 23-11-2005 13:41:07

Saludos

Tienes algun codigo en el evento OnCloseQuery del formulario Principal?

MDSato 23-11-2005 15:12:35

Hola vtdeleon,

Pues no, no tengo onCloseQuery en el formulario principal... Tampoco OnClose... :confused:

roman 23-11-2005 20:49:00

Tal como lo pintas, sobre todo no teniendo nada en el evento OnCloseQuery, no veo razón alguna para que se detenga el apagado de Windows. Quizá alguna componente que tengas en tu aplicación. Creo recordar que alguna componente de tipo TrayIcon ocasionaba esto.

// Saludos

MDSato 24-11-2005 09:19:23

Hola Roman...

Mi aplicación utiliza como componente para el TrayIcon el famoso RX (desconozco si se detectó algún problema al respecto). Aparte de ese no utilizo ninguno otro, aunque sí utilizo comunicaciones serie mediante una librería (no componente visual).

Esta noche se me ocurrió una posible alternativa, pero no sé si es viable... Consistiría en detectar el tipo de "apagado" que han solicitado (cerrar sesión, apagar, reiniciar) y resolicitarlo yo en mi aplicación justo antes de cerrarla (mediante un "shutdown" por ejemplo). ¿Qué os parece? Sinceramente no es lo más elegante, pero no se me ocurre nada más... :/

Muchas gracias a todos...

Casimiro Notevi 24-11-2005 09:51:01

por si acaso te sirve de algo puedes echar un vistazo al truco 464 de trucomanía.

MDSato 24-11-2005 10:11:47

Mmmmm... Me pongo a probar ahora mismo. Me parece una buena alternativa. Voy a ver cómo se comporta y os digo algo en cuanto pueda.

Muchas gracias Casimiro :)

MDSato 24-11-2005 10:54:27

Acabo de hacer la prueba con la solución de trucomanía, pero no consigo nada nuevo. Incluso destruyendo todas las tareas, anteriores y posteriores a la ejecución del programa. :/

Casimiro Notevi 24-11-2005 13:35:57

vas a tener que probar si se apaga dándole al botón y quitándole el cable de la electricidad... vaya a ser que ni así se apague :D


bromas aparte, es un poco raro que no consigas apagarlo de ninguna forma.

MDSato 24-11-2005 15:07:51

Pues chico... Estoy por hacer la prueba, porque no lo entiendo... Ahora voy a investigar si puedo relanzar un nuevo shutdown desde mi aplicación antes de que se cierre, pero vamos... Que no tiene mucho sentido todo esto a no ser que sea lo que comentaba Roman, alguna incompatibilidad del RX... Aunque he hecho un pequeño programa de prueba y ese se cierra perfectamente y el sistema se acaba apagando...

Un misterio digno de Expediente-X...

Casimiro Notevi 24-11-2005 20:37:09

por cierto, creo que no lo he leido, ¿qué windows usas?

Casimiro Notevi 24-11-2005 22:06:27

Por si te sirve de algo, este es el código que uso habitualmente para que se cierre sin problemas cuando uso un trxtrayicon

Código:

procedure TFmain.WMQueryEndSession(var Message: TMessage); //message WM_QUERYENDSESSION;
 begin
    Message.Result := 1; // 1=s�apagar  0=no,no apagar
    canClose := True;
    //
    Halt( Message.Result );
    Close;  // no creo que llegue a este close.
    //
end;


MDSato 25-11-2005 08:22:10

Hola Casimiro,

Gracias por la ayuda.
Pues he realizado la prueba en Windows 98, 2000 y XP, aunque realmente desarrollo en XP...
Esa opción que me has dado es la que estaba intentando efectuar. El problema que me encuentro ahora es que no es capaz de reconocerme ese mensaje y por tanto no pasa por el tratamiento del WM_QUERYENDSESSION, en cambio sí pasa por el WM_ENDSESSION.

Tengo la declaración en el private del formulario así:
procedure WMQueryEndSession (var Msg : TWMQueryEndSession); message WM_QueryEndSession;

y la implementación

procedure TFormMainImpre.WMQueryEndSession (var Msg : TWMQueryEndSession);
begin
Msg.Result := 1;
showmessage('ENTRO QUERY');
Close;
Halt;
end;

Pero nada. No aparece el mensaje. Seguiré intentando.

Muchas gracias de nuevo.

MDSato 25-11-2005 14:03:23

Estimados colegas,

Finalmente he conseguido mi propósito y os pongo la solución que he utilizado por si alguien más se encuentra en este problema.

Utilicé la opción de Roman descrita aquí (http://www.clubdelphi.com/foros/sho...860&postcount=2) redefiniendo los mensajes de este modo:
Código Delphi [-]
procedure TFormMainImpre.WMQueryEndSession (var Msg : TWMQueryEndSession);
begin
     Msg.Result := 1;
     Close;
     Halt;
end;

procedure TFormMainImpre.WMEndSession (var Msg : TWMEndSession);
begin
     ExitWindowsEx(EWX_FORCE, 0);
     inherited;
end;
Aún no sé cual es el motivo que causa este funcionamiento, pero por las pruebas que he podido realizar si el cerrado se realizaba en el tratamiento del mensaje de Windows WMQueryEndSession, todo funcionaba perfectamente, en cambio si se realizaba en WMEndSession (como en mi opinión debería ser) mi programa se cerraba correctamente pero el apagado se detenía. El problema que me encontraba ahora es que no me llegaba el mensaje WMQueryEndSession antes que el WMEndSession, sino directamente éste último. Para ello he utilizado la instrucción que veis (ExitWindowsEx(EWX_FORCE, 0);) que fuerza el cierre del programa. Es al ejecutarse esta instrucción cuando pasa por WMQueryEndSession y el cerrado y apagado son perfectos.

Muchas gracias a todos los que habéis intentado ayudarme. Habéis sido de mucha ayuda (y consuelo en la desesperación) :)

Saludos ;)

vtdeleon 25-11-2005 14:11:38

Saludos

MDSato, trata de usar las Etiquetas vB :=Delphi-SQL
Cambie tu post anterior para que veas el cambio y lo legible que es ahora ;)

MDSato 25-11-2005 14:26:10

Glups... Pues sí... Perdón por la novatada... :)

roman 25-11-2005 16:46:30

Hola,

Me da la impresión de que aquí hay una confusión sobre el objetivo a realizar.

La primera pregunta sería: ¿para qué quieres manejar los mensajes WM_QUERYENDSESSION y WM_ENDSESSION?

Al parecer, la respuesta la das desde el primer mensaje:

Cita:

Empezado por MDSato
Lo que me gustaría conseguir es que cuando apaguen el sistema (esto es, CERRAR SESION, APAGAR EL SISTEMA o REINICIAR) mi aplicación se cerrara automáticamente.

Pero, sin ánimo de ofender, esto no tiene sentido. Cuando el sistema se apague, tu aplicación seguramente se cerrará, hagas lo que hagas (o no hagas).

Normalmente estos mensajes sólo los requieres para asegurarte que tu aplicación haga las rutinas de limpieza necesarias antes de terminar. Pero la más de las veces bastará con usar los eventos OnCloseQuery y OnClose del formulario principal.

De las pocas situaciones en que es necesario usar directamente los mensajes de Windows, es cuando necesitamos distinguir si el evento OnCloseQuery se genera bien porque simplemente alguien cierre la aplicación o bien porque se cierre la sesión de Windows. Y es así porque la VCL no considera esta situación.

Pero si como dijiste:

Cita:

Empezado por MDSato
no tengo onCloseQuery en el formulario principal... Tampoco OnClose

entonces no necesitas ninguna rutina de limpieza final, y por tanto, es innecesario pienso, el uso de WM_QUERYENDSESSION y WM_ENDSESSION.

Además, estos mensajes son para avisarte que tu aplicación se va a cerrar, mas no para avisarte que cierres tu aplicación. ¿Ves la diferencia? Así que usar Close, Halt o ExitWindowsEx no tendría porque ser necesario.

Dado que no haces rutinas de limpieza en el evento OnClose ni requieres el uso de OnCloseQuery, me da la impresión de que todo este hilo se originó porque por alguna razón tu aplicación estaba impidiendo que se cerrara la sesión de Windows.

La razón habría que buscarla, en lugar de andar "cuchareando" a ver con qué comando se arregla.

Si la razón está en el RxTrayIcon entonces quizá baste con desactivarlo en el evento OnClose.

// Saludos

pborges36 08-11-2006 23:08:30

mismo problema
 
Hola MDSato, tengo el mismo problema y uso tambien el componente TrayIcon. Intente usar los procedimientos que mencionas pero no se exactamente como implementarlos, por el momento los tengo declarados en el TForm pero de ahi como sigue? Gracias.


La franja horaria es GMT +2. Ahora son las 02:57:05.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi