“无法创建表单。当前没有MDI表单处于活动状态”错误

时间:2010-10-16 13:22:47

标签: delphi

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

VAR
   FrmDereplic: TFrmDereplic;

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

重现错误的步骤:
我启动应用程序,按下按钮创建子项,我按下主(父)表单上的'x'按钮关闭应用程序,我得到一个“无法创建表单。没有MDI表单当前处于活动状态”错误。< / p>

出现错误的行在子表单中:

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;

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

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

3 个答案:

答案 0 :(得分:6)

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

所以,这是解决方案:

<强>将(S)

  

FrmDereplic:=   TFrmDereplic.Create(应用);

  

不要保存表单的属性   的OnDestroy

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

  

注意:当应用程序关闭时   下来,主要表格收到一个   OnClose事件,但任何子窗体都不会收到OnClose事件。

如果使用Application.Terminate,则不会调用onCloseQuery和onClose。对于Halt来说也是如此(但是......这太极端了吧?)。

答案 1 :(得分:3)

读取fltExtensions.ItemIndex属性时发生错误,因为它需要fltExtensions才能拥有HWND,这要求其父TFrmDereplic形式具有HWND,这需要项目的MainForm具有HWND。但是应用程序处于关闭状态,并且MainForm不再分配其HWND,因此当TFrmDereplic无法为自己获取HWND时会引发异常。

在表单的OnDestroy事件中保存您的INI数据为时已晚。您需要改为OnClose事件。

答案 2 :(得分:2)

如果您在问题中提供的代码是真实代码,那么我猜错误就在这一行:

 FrmDereplic:= TFrmDereplic.Create(TMainFrm);

我从未尝试过这个,我不确定编译器是否真的购买它(现在无法测试),但是你试图将一个类设置为MDI子窗体的所有者。而不是你应该做的

FrmDereplic:= TFrmDereplic.Create(Application);

FrmDereplic:= TFrmDereplic.Create(self);

第一个选项将应用程序设置为MDI子窗体的所有者,而第二个选项将MDI主窗体的实例设置为所有者。

希望有所帮助。 : - )