如何知道为什么'OnCloseQuery'被调用 - MDI子关闭或应用程序关闭?

Pha*_*aoh 5 delphi mdi

我目前正在开发一个MDI应用程序.
每次创建新的MDI子窗口时,它的基础数据都会动态保存到SQLite数据库并且列open设置为1,因此如果用户关闭程序并重新打开它,则会恢复窗口(同样在Anything的情况下)坏TM).
因此,每个文档始终存在于数据库中 - 如果用户单击"保存",则唯一发生的是该列persistent设置为1.
现在,如果MDI子窗口关闭,open则设置为0- 并且每一行都persistent=0 AND open=0将注定失败并将被删除.

由于这种行为,我不需要问"保存文件?" 在ApplicationClose上.
但每次MDI子窗口关闭时我需要询问.
如果Mainform.OnCloseQuery以前会被召唤MDIChild.OnCloseQuery,那将很容易做到,但遗憾的是并非如此.

总结一下:
我需要一种方法来了解是否MDIChild.OnCloseQuery被调用因为

  • 应用程序正在关闭,或
  • MDI子窗口正在关闭.

有没有办法做到这一点?

Dav*_*nan 9

您需要覆盖CloseQuery主窗体中的受保护虚拟方法.当它触发时你知道应用程序正在关闭.但是,在主窗体上CloseQuery触发OnCloseQuery事件之前,继承的实现会调用MDI子节点.

这是TCustomForm执行CloseQuery:

function TCustomForm.CloseQuery: Boolean;
var
  I: Integer;
begin
  if FormStyle = fsMDIForm then
  begin
    Result := False;
    for I := 0 to MDIChildCount - 1 do
      if not MDIChildren[I].CloseQuery then Exit;
  end;
  Result := True;
  if Assigned(FOnCloseQuery) then FOnCloseQuery(Self, Result);
end;
Run Code Online (Sandbox Code Playgroud)

请注意,MDI子项CloseQuery之前会收到通知Self,即主表​​单.

因此,在您的主要表单中,您需要:

type
  TMainForm = class(TForm);
  private
    FCloseQueryExecuting: Boolean;
  protected
    function CloseQuery: Boolean; override;
  public
    property CloseQueryExecuting: Boolean read FCloseQueryExecuting;
  end;
Run Code Online (Sandbox Code Playgroud)

然后是一个看起来像这样的实现:

function TMainForm.CloseQuery: Boolean; 
begin
  FCloseQueryExecuting := True;
  try
    Result := inherited CloseQuery;
  finally
    FCloseQueryExecuting := False;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

然后,MDI子项可以FCloseQueryExecutingOnCloseQuery事件中检查主窗体属性的状态.