Where is CanClose?

I want to prevent the user from closing the application.
When windows closes I want the application to do some tasks then close and then windows close.

In Form1.FormCloseQuery is CanClose := false; // user cannot close the app.

Form1.OnWindowsShutDown;
begin
 DoTasks;

 Form1.CanClose := true;  // No such variable.
 Application.CanClose := true;  // No such variable.

 Application.Terminate;
end;

Application.Terminate needs CanClose to be true but I cannot find a way to set it true, it doesn't seem to be a property of the form or of the application.

frogAsked:
Who is Participating?
 
HypoviaxConnect With a Mentor Commented:
You assign the action property in formclose:

action:=canone;

By setting action to canone the user cannot close the application

The other settings you can assign to the action property are:

caNone, caHide, caFree, caMinimize

The cafree would enable the form to be closed

Regards
0
 
ceoworksConnect With a Mentor Commented:
Hi frog,

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    btnCloseAllow: TButton;
    btnCloseDecline: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btnCloseAllowClick(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure btnCloseDeclineClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  IsCloseAllowed: Boolean;

implementation

{$R *.dfm}

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

procedure TForm1.btnCloseAllowClick(Sender: TObject);
begin
  IsCloseAllowed := True;
end;

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

procedure TForm1.btnCloseDeclineClick(Sender: TObject);
begin
  IsCloseAllowed := False;
end;

end.

Regards,

Oktay Sancak
0
 
manganzonCommented:
Hi. I understand some parts of your question: 1) u dont want the user to close your app.
2) u want ur app to do some stuff when it detects the user is closing windows.

1) To acompplisth the first goal u can certainly use canclose property but the user will still be able to kill the process. You can create a library to prevent the user to close the process too with madshi code hook (use this is your app runs in the background cause if your app is visible user will be able to close it, in this case you should use both canclose property and this code so that it will be very hard for the user to close your program):

library  dontcloseme;



uses
  Windows,
  madRemote,
  madCodeHook,
  madStrings;

var TerminateProcessNext : function (processHandle, exitCode: dword) : bool; stdcall; //this is the original function

function ThisIsOurProcess(processHandle: dword) : boolean; //just a function to check is this is our process
var pid   : dword;
    arrCh : array [0..MAX_PATH] of char;
begin
  pid := ProcessHandleToId(processHandle);
  result := (pid <> 0) and ProcessIdToFileName(pid, arrCh) and
            (PosText('Your_application_exe_name_here.EXE', arrCh) > 0);
end;

function TerminateProcessCallback(processHandle, exitCode: dword) : bool; stdcall;// the callback function
begin
  if ThisIsOurProcess(processHandle) then begin
    result := false;
    SetLastError(ERROR_ACCESS_DENIED);  //if this is our process, then set an error
  end else
    result := TerminateProcessNext(processHandle, exitCode);//else terminate the process
end;

begin
  HookAPI('kernel32.dll', 'TerminateProcess', @TerminateProcessCallback, @TerminateProcessNext); //hook the API
end.

You can download the mad code hooks in madshi's webpage, here: www.madshi.net


To do the second thing you could use this code:


unit Unit1;

interface

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

type
  TForm1 = class(TForm)

    procedure EndSMsg(var T : TMessage);message  WM_QUERYENDSESSION;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Plop: Boolean;
implementation

{$R *.dfm}

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

procedure TForm1.EndSMsg(var T : TMessage);
begin
  T.result := 0;{this will stop windows shutdown}
  if T.lparam = 0 then
    begin
{The tasks you want to do}
    end
  else if (DWORD(T.lparam) and ENDSESSION_LOGOFF) =
                                 ENDSESSION_LOGOFF then
    begin
{The tasks you want to do}
    end;
Plop:=True;
T.result:=1;{after you do the stuff you will continue with windows shutdown}
Application.Terminate;
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
Canclose:= Plop {THIS PART IS CEOWORKS CODE FROM THE PREVIOUS POST, Im just mixing this with my code}
end;


end.


Hope this helps.
Regards.
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

 
ceoworksCommented:
Oh sorry, i didn't noticed that you are talking about to prevent the Windows Shutdown. My answer is not quite..
0
 
HypoviaxCommented:
I actually think our suggestions ceoworks are quite correct. The questioner is asking how can he prevent users closing the program, both yourself and i have answered that in similar fashion so i do believe that our answers are correct.

Regards,

Hypoviax
0
 
frogAuthor Commented:
Thanks All.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.