Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


Tip of the Day
Language: Pascal
Expertise: Beginner
May 13, 1997

How to prevent user shutting Windows down while Delphi app is running

Question:
How can I trap the API message sent by Windows 95 on closure, to prevent a user shutting Windows down when a Delphi application is running?

Answer:
There are two ways to approach this problem. One is strictly Delphi; the other involves creating a message handler for the WM_CLOSE message in Windows. Let's look at the former method first.

The easiest way to decide whether to allow a user to close a program is with the OnCloseQuery method of the main form. If you open that method, you'll see the following:

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

end;
The most important part of that method is the CanClose formal parameter. If False, the window will not be allowed to close. If true, the program will close. Here's an example. Let's say that while some background processing is occuring, you have a Boolean variable called "ProcessRunning" set to true during the course of the process. If the user tries to close the program during the run you could do something like this:
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  if ProcessRunning then
    CanClose := False
  else
    CanClose := True;
end;
The point to this is to check certain conditions within the program. If the criteria for closing is correct, you can close the window. Otherwise, leave it up.

You'd do the same thing with a custom message handler for the WM_CLOSE message. The only difference is, you have to create the handler. To do this, look at the following section of code taken out of a program that I wrote that is set up to handle WM_CLOSE:

  private
    procedure WMClose(var Msg : TWMClose); message WM_CLOSE;
  public

  end;

var
  Form1: TForm1;
  CloseDown : Boolean;

implementation

{$R *.DFM}

procedure TForm1.WMClose(var Msg : TWMClose);
begin
  if NOT CloseDown then
    Msg.Result := 0
  else
    inherited;
end;
If you're new to creating custom Windows message handlers, while not a trivial thing, it's not that hard to do. It just requires some work. I won't go into a long discussion about Windows message handlers. WM_CLOSE happens to be a fairly simple message to handle, but there are more complex ones out there that take much more space than a simple e-mail reply. So I'll just tell you how to go about handling the message, then let you play with the code:

First, in the private section of the form's type declaration, you must declare the handler. In this case, I've declared it as:

procedure WMClose(var Msg : TWMClose); message WM_CLOSE;
You can name the procedure anything you like.

As far as the implementation is concerned, to deny closure, we have to set the message's result to 0. To allow closure, we just call the inherited WM_CLOSE handler.

procedure TForm1.WMClose(var Msg : TWMClose);
begin
  if NOT CloseDown then
    Msg.Result := 0
  else
    inherited;
end;
By the way, in the sample program I have two buttons that set the CloseDown variable to True or False.

As you can see, the principle is exactly the same as using the OnCloseQuery method of the form. But you can also see that to accomplish the same task, a bit more work had to be done. So a good "rule of thumb" is to use Delphi's built-in capabilities as much as possible, and to use only custom message handlers for events that aren't handled by default in Delphi.

DevX Pro
 
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date