2006. október 11., szerda

Preventing a user from closing a window except at shutdown or restart


Problem/Question/Abstract:

How to oreventing a user from closing a window except at shutdown or restart

Answer:

We all know how to prevent a window from closing: Simply write event code for the OnCloseQuery event and set CanClose to False. Once that's done, no matter what a user presses, the window won't close. Here's some code:

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := False;
end;

But what if you wanted to be able to close a window only when you reboot the machine? With the scenario above, that would be impossible. Fortunately though, there is a solution, and it resides in the windows message WM_QUERYENDSESSION.

WM_QUERYENDSESSION is generated by Windows when the OS is resetting: Either at a shutdown or a restart. Using this message, we can set a boolean flag variable and interrogate its value in OnCloseQuery to allow us to close the window and reset the operating system. Look at the unit code below:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes,
  Graphics, Controls, Forms, Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  private
    procedure WMQueryEndSession(var Message: TWMQueryEndSession);
      message WM_QUERYENDSESSION;
  public
    WindowsClosing: Boolean;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  WindowsClosing := False;
end;

procedure TForm1.WMQueryEndSession(var Message: TWMQUERYENDSESSION);
begin
  WindowsClosing := True;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := WindowsClosing;
end;

end.

As you can see, I've created a public variable called WindowsClosing. When WM_QUERYENDSESSION fires, it sets the variable to True. Then in OnCloseQuery, CanClose is set to the value of WindowsClosing. Notice that I set WindowsClosing to False in OnCreate. This is purely for initialization purposes to make sure that previous attempts to close the window are foiled.

Nincsenek megjegyzések:

Megjegyzés küldése