"无法创建表单.当前没有MDI表单处于活动状态"错误

WeG*_*ars 5 delphi

我有一个MDI主(父)表单和一个MDI子表单.我在运行时创建了这样的子代:

VAR
   FrmDereplic: TFrmDereplic;

procedure TMainFrm.Button2Click(Sender: TObject);
begin
 FrmDereplic:= TFrmDereplic.Create(MainFrm);
 FrmDereplic.Show;
end;
Run Code Online (Sandbox Code Playgroud)

重现错误的步骤:
我启动应用程序,按下按钮创建子项,我按下主(父)表单上的'x'按钮关闭应用程序,我得到一个"无法创建表单.没有MDI表单是目前有效"错误.

出现错误的行在子窗体中:

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;
Run Code Online (Sandbox Code Playgroud)

我将很多表单的属性(以及其他控件属性)保存到INI文件中.但是当我尝试保存fltExtensions.ItemIndex(这是一个TFilterComboBox)时它才会失败.如果我评论那条线它完美无缺.

知道为什么它在我实际关闭应用程序时尝试创建一个表单?????????

WeG*_*ars 6

我查看了一些网站,发现了问题.如果所有者是应用程序而不是主要表单,看起来更好.Remy Lebeau认为真正的问题在于儿童形式的OnDestroy.保持过滤器的窗口没有有效的句柄,然后调用OnDestroy.因此,更改销毁顺序使TFrmDereplic.OnDestroy有机会正确执行.

所以,这是解决方案:

SOLUTION(S)

FrmDereplic:= TFrmDereplic.Create(Application);

要么

不要在OnDestroy中保存表单的属性

第二个需要额外的代码行,因为OnClose甚至不总是被调用.这是从Delphi HELP中提取的:

注意:当应用程序关闭时,主窗体会收到OnClose事件,但任何子窗体都不会收到OnClose事件.

如果使用Application.Terminate,则不会调用onCloseQuery和onClose.Halt也是一样(但是......这太极端了吧?).