5

現在、MDIアプリケーションを開発しています。
新しいMDI子ウィンドウが作成されるたびに、その基になるデータがオンザフライでSQLiteデータベースに保存され、列openがに設定される1ため、ユーザーがプログラムを閉じて再度開くと、ウィンドウが復元されます(Anythingの場合も同様)。悪いTM)。
したがって、すべてのドキュメントは常にデータベースに存在します。ユーザーが[保存]をクリックした場合に発生するのは、列persistentがに設定されていることだけ1です。
これで、MDI子ウィンドウが閉じている場合、openは-に設定され0、すべての行persistent=0 AND open=0が運命づけられて削除されます。

この動作の結果として、「ドキュメントを保存しますか?」と尋ねる必要はありません。ApplicationCloseで。
ただし、MDIの子ウィンドウを閉じるたびに質問する必要があります以前に呼び出された
場合、それはすべて簡単に実行できますが、残念ながらそうではありません。Mainform.OnCloseQueryMDIChild.OnCloseQuery

要約すると、呼び出された
かどうかを知る方法が必要です。MDIChild.OnCloseQuery

  • アプリケーションがシャットダウンしている、または
  • MDI子ウィンドウが閉じられています。

これを行う方法はありますか?

4

1 に答える 1

9

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ます。

于 2012-12-27T12:30:04.743 に答える