Как узнать, почему вызывается OnCloseQuery - дочерний MDI закрыт или приложение завершено?

В настоящее время я разрабатываю приложение MDI.
Каждый раз, когда создается новое дочернее окно MDI, его основные данные на лету сохраняются в базе данных SQLite и столбце. open установлен в 1, поэтому, если пользователь закрывает программу и открывает ее снова, окна восстанавливаются (также в случае Anything Bad TM).
Таким образом, каждый документ всегда присутствует в базе данных - единственное, что происходит, если пользователь нажимает "Сохранить", это то, что столбец persistent установлен в 1,
Теперь, если дочернее окно MDI закрыто, open установлен в 0 - и каждый ряд с persistent=0 AND open=0 обречен и будет удален.

В результате этого поведения мне не нужно спрашивать "Сохранить документы?" по заявкеЗакрыть.
Но мне нужно спрашивать каждый раз, когда закрывается дочернее окно MDI.
Это все будет легко сделать, если Mainform.OnCloseQuery будет вызван раньше MDIChild.OnCloseQuery но, к сожалению, это не так.

Подвести итог:
Мне нужен способ узнать, MDIChild.OnCloseQuery называется потому что

  • приложение закрывается или
  • дочернее окно MDI закрывается.

Есть какой-либо способ сделать это?

1 ответ

Решение

Вам необходимо переопределить защищенный виртуальный метод CloseQuery в вашей основной форме. Когда это срабатывает, вы знаете, что приложение закрывается. Но унаследованные вызовы реализации CloseQuery на MDI детей, прежде чем уволить OnCloseQuery событие в основной форме.

Здесь 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;

Обратите внимание, что дети MDI получают свои CloseQuery уведомления до этого для Selfт.е. основная форма.

Итак, в вашей основной форме вам нужно:

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

а затем реализация, которая выглядит так:

function TMainForm.CloseQuery: Boolean; 
begin
  FCloseQueryExecuting := True;
  try
    Result := inherited CloseQuery;
  finally
    FCloseQueryExecuting := False;
  end;
end;

Затем дети MDI могут проверить состояние основной формы FCloseQueryExecuting собственность в их OnCloseQuery События.

Другие вопросы по тегам