When the main form is closed then the application terminates which frees the main form which in turn frees the forms owned by it. The owned forms are not closed, just freed, therefore their OnClose
event is normally not triggered at all.
If you see ShowMessage
being called from the owned form's OnClose
event but the dialog doesn't show up it's probably because the application is already terminated and no longer processing messages. This means that the owned form's OnClose
event is triggered by somewhere in your own code but too late.
One way to reproduce this behaviour is to post WM_CLOSE
message to the owned form from the main form's OnClose
event. The message is then processed by the owned form at a later moment when the application is already terminated any attempt to call ShowMessage or any modal form has no effect anymore.
I agree with Michael that OnCloseQuery
is better suited for the purpose of displaying a prompt to the user. Unfortunately this alone doesn't help since the owned forms are being freed not closed. You have to call their OnCloseQuery
event manually, for example:
procedure TFormMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
I: Integer;
begin
CanClose := False;
for I := 0 to ComponentCount - 1 do
if Components[I] is TCustomForm then
if not TCustomForm(Components[I]).CloseQuery then
Exit;
CanClose := True; // or another check if the main form can be closed, too
end;