【发布时间】:2014-01-21 16:44:18
【问题描述】:
我有一个主窗体和另一个“辅助”窗体。如果我先关闭第二个,它的OnClose 处理程序会被调用。不幸的是,如果我先关闭主窗体,应用程序将终止,并且不会调用辅助窗体的 OnClose。这是一个问题,因为我想在每个表单关闭之前保存它们的位置和大小。我该如何解决这个问题?
【问题讨论】:
我有一个主窗体和另一个“辅助”窗体。如果我先关闭第二个,它的OnClose 处理程序会被调用。不幸的是,如果我先关闭主窗体,应用程序将终止,并且不会调用辅助窗体的 OnClose。这是一个问题,因为我想在每个表单关闭之前保存它们的位置和大小。我该如何解决这个问题?
【问题讨论】:
处理这个问题的一个好地方是主窗体的OnCloseQuery 事件。
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var i : integer;
begin
CanClose := true;
if Application.MainForm = self then begin
CanClose := MessageDlg('Close the application?', mtConfirmation,
[mbYes, mbNo], 0) = mrYes;
if CanClose then
for i := 0 to Screen.FormCount - 1 do
if Screen.Forms[i] <> self then Screen.Forms[i].Close;
end;
end;
上面建议的第一个检查仅在您有多个正在使用的主窗体实例时才有用。对self 进行第二次检查是必要的,以防止再次进入。
【讨论】:
Visible 属性。在OnDestroy 中始终是False,但在调用主窗体的OnCloseQuery 处理程序时它具有正确的值。
Application.Terminate,它将不会被调用——大概如果你这样做是因为你确实希望应用程序立即终止。在 Windows 关闭期间处理强制终止是完全不同的问题,应单独处理。请参阅:stackoverflow.com/q/10745151/327083
您可以使用 OnDestroy 而不是 OnClose 来保存它。而且您可能应该在关闭后销毁您的辅助表单(在打开之前创建):
Form2 := TForm2.Create(Application);
Form2.Open;
在 Form2.OnClose 中:
Action := caFree;
您还需要删除 .dpr 中自动创建辅助表单的行:
Application.CreateForm(TForm2, Form2);
也许禁用这个自动创建。在 D7 中:工具>>环境选项>>设计器>>禁用“自动创建...”
执行所有这些操作将为您节省一些内存。当您希望用户在返回主窗体之前关闭辅助窗体时,还可以考虑使用 ShowModal 而不是 Show。
【讨论】:
OnDestroy 总是会被调用。唯一的问题是我也想保存可见性,但Visible 在OnDestroy 中始终是False :(