Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is MessageDlg not shown after a form is freed via OnClose event (in a thread)

Given this scenario:

procedure TForm2.Button1Click(Sender: TObject);
var
  Form: TForm;
begin
  Form := TForm.Create(nil);
  Form.OnClose := FormClosed;
  Form.Show;
  Sleep(200);
  TThread.CreateAnonymousThread(
    procedure
    begin
      TThread.Synchronize( nil, 
        procedure 
        begin 
          Form.Close; 
          MessageDlg('Testing', mtInformation, [mbok], 0); 
        end);
    end).Start;
end;

procedure TForm2.FormClosed(Sender: TObject; var Action: TCloseAction);
begin
  Action := TCloseAction.caFree;
end;

My MessageDlg call is not displayed (the result of this call is always mrCancel (2)).

After digging around, it's related to the OnClose event and setting the Action to caFree.

Changing Form.Close to Form.Free and removing the OnClose event entirely displays MessageDlg ok. Placing MessageDlg before the call to Form.Close works ok. Originally I thought scope of my Form variable might have caused the problem but declaring Formas a private field in TForm2 instance doesn't solve the problem.

My aim was to display a splash form, execute my thread, then through call backs of said thread, close the Splash form and display dialog where appropriate to the user.

For clarity, why does this occur?

like image 401
Jason Avatar asked Dec 25 '22 23:12

Jason


1 Answers

What is happening is that the dialog's owning window is the form that is being closed. When the dialog starts its modal message loop, the form is released and takes down its owned windows with it. Including the dialog.

Test this out, to give you more confidence that what I state above is correct, by replacing the call to show the dialog first with

MessageBox(0, ...);

and then with

MessageBox(Form.Handle, ...);

That is, be explicit about the dialog's owner.

The first version, with no owner, will show the dialog. The second won't because it replicates the scenario in your code.

like image 117
David Heffernan Avatar answered Dec 29 '22 00:12

David Heffernan