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)
-   -   Problema con el WMQueryEndSession (https://www.clubdelphi.com/foros/showthread.php?t=38325)

mierda 11-12-2006 20:06:38

Problema con el WMQueryEndSession
 
Hola, teniendo el siguiente ejemplo ...

Código Delphi [-]
 
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;
type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
    procedure WMQueryEndSession (var Msg: TWMQueryEndSession);
    message WM_QueryEndSession;   // esta funcion intercepta el mensaje que le lanza el windows a cerrar a la ventana de delphi
  end;
var
  Form1: TForm1;
  EndSessionFlags: integer; // esti es para q no se cierre hasta que no me de la gana
  ProcessStatus: integer;  // idem de arriba

implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.WMQueryEndSession(var Msg: TWMQueryEndSession);
begin
showmessage (inttostr(msg.source) + ' ' + Msg.Result);
case ProcessStatus of
    0: // Primera vez
      begin
        ProcessStatus := 1;        // Evita entrar aquí de nuevo
        EndSessionFlags := Msg.Source;  // Guarda la forma de cierre
        Msg.Result := 0;           // Decimos a Windows que no termine
                      // realizar el proceso dentro de unos milisegundos
      end;
    1: // Estamos procesando
        Msg.Result := 0;      // Decimos a Windows que no estamos listos
    2: // Hemos terminado de realizar el proceso
      begin
        ProcessStatus := 0;   // Listo para la próxima (si corresponde)
        Msg.Result := 1;      // Estamos listos. Se puede cerrar Windows
      end;
    end;
end;
end.

da igual que yo le mande cerrar la sesion, apagar o reiniciar ... el showmessage me muestra que el valor siempre es 0, con lo que siempre me cierra la sesion.

Alguna idea de por que pasa esto? Un saludo.

PD: falta un trocito de codigo que pone el 2: //Que hemos terminado de realizar el proceso, pero eso no es importante ... trabajo con delphi7 y win2000, pero en xp tambien me pasa.

roman 11-12-2006 21:16:46

No entiendo bien en qué forma planeas usar el Msg.Source pero haciendo algunas pruebas me parece que Delphi tiene un pequeño bug. La declaración de TWMQueryEndSession es:

Código Delphi [-]
TWMQueryEndSession = packed record
  Msg: Cardinal;
  Source: Longint;
  Unused: Longint;
  Result: Longint;
end;

pero la documentación en el SDK de Windows dice:

Cita:

wParam
This parameter is reserved for future use.

lParam
If this parameter includes ENDSESSION_LOGOFF, the user is logging off. (Note that this parameter is a bit mask. To test for this value, use a bit-wise operation; do not test for equality.)
If this parameter is zero, the system is shutting down or restarting (it is not possible to determine which event is occurring).
es decir, según yo entiendo, la declaración en Delphi está alrevés y debería ser:

Código Delphi [-]
TWMQueryEndSession = packed record
  Msg: Cardinal;
  Unused: Longint;
  Source: Longint;
  Result: Longint;
end;

Aunque no lo puedo asegurar, parece ser corroborado por esta prueba:

Código Delphi [-]
procedure TForm1.WMQueryEndSession(var Msg: TWMQueryEndSession);
begin
  inherited;

  if Msg.Source and ENDSESSION_LOGOFF <> 0 then
    ShowMessage('You are logging off...')
  else
    ShowMessage('You are shutting down or restarting...');

  Msg.Result := 0;
end;

siempre muestra el segundo mensaje. Pero si pongo

Código Delphi [-]
procedure TForm1.WMQueryEndSession(var Msg: TWMQueryEndSession);
begin
  inherited;

  if Msg.Unused and ENDSESSION_LOGOFF <> 0 then
    ShowMessage('You are logging off...')
  else
    ShowMessage('You are shutting down or restarting...');

  Msg.Result := 0;
end;

sí me pone el primer mensaje cuando intento cerrar la sesión.

Esto, con Delphi 7.

// Saludos

mierda 12-12-2006 10:04:04

hola, ante todo gracias por contestar
 
Hola, ante todo, gracias por contestar. Tengo un messenger corporativo de la empresa, que se arranca cuando se inicia la sesion. Entonces, intento conseguir que cuando alguien cierre la sesion o apaga el ordenador, se guardan unos valores en unas tablas.

Por lo que intento capturar ese cierre de sesion o apagado, hago mis cosas y sigue cerrandose o apagandose

Código Delphi [-]
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;
type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure WMQueryEndSession (var Msg: TWMQueryEndSession);
    message WM_QueryEndSession;   // esta funcion intercepta el mensaje que le lanza el windows a cerrar a la ventana de delphi
  end;
var
  Form1: TForm1;
  EndSessionFlags: integer; // esti es para q no se cierre hasta que no me de la gana
  ProcessStatus: integer;  // idem de arriba

implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.WMQueryEndSession(var Msg: TWMQueryEndSession);
begin
//showmessage (inttostr(Msg.Unused) + ' ' + inttostr(Msg.Result));
Timer1.Enabled := true;
case ProcessStatus of
    0: // Primera vez
      begin
        ProcessStatus := 1;        // Evita entrar aquí de nuevo
        EndSessionFlags := Msg.Unused;  // Guarda la forma de cierre
        Msg.Result := 0;           // Decimos a Windows que no termine
                      // realizar el proceso dentro de unos milisegundos
      end;
    1: // Estamos procesando
        Msg.Result := 0;      // Decimos a Windows que no estamos listos
    2: // Hemos terminado de realizar el proceso
      begin
        ProcessStatus := 0;   // Listo para la próxima (si corresponde)
        Msg.Result := 1;      // Estamos listos. Se puede cerrar Windows
      end;
    end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
ProcessStatus := 2;       // Señal para indicar que hemos terminado
ExitWindowsEx(EndSessionFlags, 0);  // Cerramos Windows
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ProcessStatus := 0;
end;
end.

Para eso intento utilizar el endsessionflags que ha capturado el mensaje que han mandado de cerrar o apagar. Pero el problema es q siempre me cierra la sesion .... nunca me apaga ... aun cambiando por "Msg.Unused".

Un saludo

roman 12-12-2006 19:03:21

Hola,

No entiendo por qué intentas este mecanismo. ¿No te basta guardar los valores que mencionas en cuanto recibes por primera vez el mensaje? ¿Por qué quieres hacerlo por partes? Piensa que eso puede complicar las cosas porque tu aplicación no será la única involucrada en el proceso de cierre del sistema. Otras aplicaciones pueden incluso detener el proceso y tu aplicación lo está forzando.

// Saludos


La franja horaria es GMT +2. Ahora son las 02:17:14.

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