Delphi – “Cannot create form. No MDI forms are currently active” error

delphi

I have a MDI main (parent) form and a MDI child form. I create the child at runtime like this:

VAR
   FrmDereplic: TFrmDereplic;

procedure TMainFrm.Button2Click(Sender: TObject);
begin
 FrmDereplic:= TFrmDereplic.Create(MainFrm);
 FrmDereplic.Show;
end;

Steps to reproduce the error:
I start the app, I press the button to create the child, I press the 'x' button on main (parent) form to close the application and I get an "Cannot create form. No MDI forms are currently active" error.

The line on which the error appears is in the child form:

procedure TFrmDereplic.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 Action:= caFree;
end;

procedure TFrmDereplic.FormDestroy(Sender: TObject);
VAR MyIniFile: TCubicIniFile;
begin
 MyIniFile:= TCubicIniFile.Create(AppINIFile);
 TRY
  with MyIniFile DO
  begin
   if WindowState<> wsMaximized then
    begin
     // save form's screen pos
     ...
    end;
   WriteInteger  ('Dereplicator', 'fltExtensions', fltExtensions.ItemIndex);  <----- HERE
 FINALLY
  FreeAndNil(MyIniFile);
 END;
end;

I save lots of form's properties (and other's controls properties) to the INI file. But it only fails when I try to save fltExtensions.ItemIndex (which is a TFilterComboBox). If I comment that line it works perfectly.

Any idea why it tries to create a form when I actually closed the application?????????

Best Answer

I look on some web sites and just found the problem. It looks like it is preferably to have the Owner set to Application, instead of the main form. Remy Lebeau suggests that the real problem is in the OnDestroy of the the child form. There is no valid handle to the window that holds the filter then the OnDestroy is called. So, changing the destruction order gives a chance to TFrmDereplic.OnDestroy to execute properly.

So, here is the solution:

SOLUTION(S)

FrmDereplic:= TFrmDereplic.Create(Application);

or

Do not save form's properties in OnDestroy

The second one requires few extra lines of code as the OnClose even is not always called. This was extracted from Delphi HELP:

Note: When the application shuts down, the main form receives an OnClose event, but any child forms do not receive the OnClose event.

If you use Application.Terminate, then onCloseQuery and onClose will not be called. Same for Halt (but... this is way too extreme, right?).

Related Topic