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

delphi, delphi-7

Solution

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;

Problem

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 :(

Original source