Richard Woolf
Richard Woolf

Reputation: 579

Delphi: Close all forms (except MainForm), but, ignore any OnCloseQuery dialogs

Basically, I'm using a TTimer event to close all the open forms and bring the user back to the main form. I could iterate through Screen.Forms:

for i := 0 to Screen.Formcount - 1 do
  Screen.Forms[i].close;

The problem is the OnCloseQuery events on some of those forms - they pop up MessageDlg's which interrupt this process :(

Upvotes: 4

Views: 6160

Answers (2)

S. Sami
S. Sami

Reputation: 23

for i := 1 to Screen.Formcount - 1 do
  Screen.Forms[i].close;

Initial the value i with 1, not 0.

Upvotes: -1

Sertac Akyuz
Sertac Akyuz

Reputation: 54812

You can use a flag in your main form that your other forms would check before asking the user whether to proceed or not. Something like this:

unit1

type
  TForm1 = class(TForm)
    ..
  public
    UnconditinalClose: Boolean;
  end;

..

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  UnconditinalClose := True;
end;

unit 2:

implementation

uses
  unit1;

procedure TForm2.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := unit1.Form1.UnconditinalClose;
  if not CanClose then
    // ask the user if he/she's sure he/she wants to close
end;


One other solution could be detaching OnCloseQuery event handlers of other forms. This would only be practical if these other forms are released (freed) when closing, not hidden (edited to reflect Rob's comment):

procedure TForm1.Timer1Timer(Sender: TObject);
var
  i: Integer;
  SaveHandler: TCloseQueryEvent;
begin
  for i := 0 to Screen.Formcount - 1 do
    if Screen.Forms[i] <> Self then begin
      SaveHandler := Screen.Forms[i].OnCloseQuery;
      Screen.Forms[i].OnCloseQuery := nil;
      Screen.Forms[i].Close;
      Screen.Forms[i].OnCloseQuery := SaveHandler;
    end;
end;

Upvotes: 7

Related Questions