I am currently developing an MDI application.
Every time a new MDI child window is created, it's underlying data is saved on the fly to an SQLite database and the column open
is set to 1
, so if the user closes the program and reopens it, the windows are restored (also in case of Anything BadTM).
So every document is always present in the database - the only thing that happens if the user clicks "Save" is that the column persistent
is set to 1
.
Now if an MDI child window is closed, open
is set to 0
- and every row with persistent=0 AND open=0
is doomed and will be deleted.
As a result of this behaviour I don't need to ask "Save documents?" on ApplicationClose.
But I do need to ask every time an MDI child window is closed.
That would all be easy to do if Mainform.OnCloseQuery
would be called before MDIChild.OnCloseQuery
, but sadly that's not the case.
To sum it up:
I need a way to know whether MDIChild.OnCloseQuery
is called because
Is there any way to do this?
You need to override the protected virtual method CloseQuery
in your main form. When that fires you know the app is going down. But the inherited implementation calls CloseQuery
on the MDI children before firing the OnCloseQuery
event on the main form.
Here is the TCustomForm
implementation of 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;
Notice that the MDI children get their CloseQuery
notifications before that for Self
, i.e. the main form.
So in your main form you need:
type
TMainForm = class(TForm);
private
FCloseQueryExecuting: Boolean;
protected
function CloseQuery: Boolean; override;
public
property CloseQueryExecuting: Boolean read FCloseQueryExecuting;
end;
and then an implementation that looks like this:
function TMainForm.CloseQuery: Boolean;
begin
FCloseQueryExecuting := True;
try
Result := inherited CloseQuery;
finally
FCloseQueryExecuting := False;
end;
end;
Then the MDI children can check the state of the main form's FCloseQueryExecuting
property in their OnCloseQuery
events.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With