我有一个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)时它才会失败。如果我评论该行,那就完美了。
当我实际关闭应用程序时,不知道为什么它会尝试创建一个表单??????????
答案 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主窗体的实例设置为所有者。
希望有所帮助。 : - )