Jump to content
shineworld

FormDestory call order

Recommended Posts

Hi all,

 

I'm moving a big project, about 1.500.000 code lines from Delphi 2006 to Syndey,

but I'm in trouble with how Syndey destroys objects in program termination.

 

Sample:

A very Dummy application with 1 form without any other code than a comment in TForm3.FormDestory to

place a breakpoint:

 

unit Unit3;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
  TForm3 = class(TForm)
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

procedure TForm3.FormDestroy(Sender: TObject);
begin  // < placed breakpoint here!!!
  //
end;

end.

 

A very simple project with a string assignment to catch the main flow (in S := ''; ) after Application Run:
 

program Project2;

uses
  Vcl.Forms,
  Unit3 in 'Unit3.pas' {Form3};

{$R *.res}

var
  S: string;
begin
  S := 'asdfasdf';

  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm3, Form3);
  Application.Run;

  S := ''; ; << placed break point here

end.

In BDS 2006 if I run this code and exit program first break at Form3.FormDestroy,

then breaks in main at S := ''. RIGHT !

In Sydney first, break in the main at S := '', then goes to Form3.FormDestry.

 

What has changed so much the Delphi behavior?

if I add a Form3.DoubleClick event with
Application.Terminate

I got also an environment error:

[50164E97]{rtl270.bpl  } System.Classes.TList.Get (Line 4972, "System.Classes.pas" + 2) + $A
[50EBFC4B]{vcl270.bpl  } Vcl.AppEvnts.TMultiCaster.GetAppEvents (Line 657, "Vcl.AppEvnts.pas" + 1) + $B
[50EBF60E]{vcl270.bpl  } Vcl.AppEvnts.TMultiCaster.DoActivate (Line 425, "Vcl.AppEvnts.pas" + 5) + $9
[50E5A73F]{vcl270.bpl  } Vcl.Forms.TApplication.WndProc (Line 10617, "Vcl.Forms.pas" + 126) + $C
[50181450]{rtl270.bpl  } System.Classes.StdWndProc (Line 18021, "System.Classes.pas" + 😎 + $0
[50E5B23F]{vcl270.bpl  } Vcl.Forms.TApplication.ProcessMessage (Line 11028, "Vcl.Forms.pas" + 23) + $1
[50E5B282]{vcl270.bpl  } Vcl.Forms.TApplication.HandleMessage (Line 11058, "Vcl.Forms.pas" + 1) + $4
[50E5B5B5]{vcl270.bpl  } Vcl.Forms.TApplication.Run (Line 11196, "Vcl.Forms.pas" + 26) + $3
[0051E178]{bds.exe     } bds.bds (Line 222, "" + 13) + $2

😞 

test.7z

Edited by shineworld

Share this post


Link to post
Guest

my test in RAD 10.3.3 Arch and RAD 10.4.1 Arch  = same behavior! BUT none error!

  1.   Application.Terminate; // Debug stop 1
  2.   S := ''; // Debug stop 2
  3.   lStopHere := '';  // Debug stop 3
 // DPR file
Application.Run;
  S := ''; // Debug stop 2

// unit TForm
{$R *.dfm}

procedure TForm3.FormDblClick(Sender: TObject);
begin
  Application.Terminate; // Debug stop 1

end;

procedure TForm3.FormDestroy(Sender: TObject);
var
  lStopHere:string;
begin
  lStopHere := '';  // Debug stop 3
end;

 

I don't know if you know, but a "FORM" is in an eternal loop when running, that is, inside a loop and the system is attentive to any message to process.
Thus, when the "RUN" loses focus, the variable "S" will be processed, and, the system seeing that there are other tasks before destroying the form, it continues to execute the other messages ...

 

Quote

unit Vcl.Forms.pas, line 10888 .... REPEAT looping

 

Quote

Call Terminate to end the application programmatically. By calling Terminate rather than freeing the application object, you allow the application to shut down in an orderly fashion.

Terminate calls the Windows API PostQuitMessage function to perform an orderly shutdown of the application. Terminate is not immediate.

Terminate is called automatically on a WM_QUIT message and when the main form closes.

 

NOTE: It reminds me of when I used "Clipper Summer 87", and, we had to use "WHILE" to show screens or a pseudo-DBGrid

 

try this:

// DPR file
Application.Run;

  S := '';  // Debug DONT stop here

// unit FORM
procedure TForm3.FormDblClick(Sender: TObject);
begin
 Halt; //Application.Terminate; // Debug stop 1

end;

procedure TForm3.FormDestroy(Sender: TObject);
var
  lStopHere:string;
begin
  lStopHere := '';  // Debug stop 2
end;
Quote

HALT( code );

Initiates the abnormal termination of a program.

Halt performs an abnormal termination of a program and returns to the operating system.

To perform a normal termination of a Delphi application, call the Terminate method on the global Application object.

If the application does not use a unit that provides an Application object, call the Exit procedure from the main Program block.

Exitcode is an optional expression that specifies an exit code for the program

 

hug

Edited by Guest

Share this post


Link to post

You should take a look on AddExitProc: http://docwiki.embarcadero.com/Libraries/Sydney/en/System.SysUtils.AddExitProc

procedure DoOnExit;
var
  s: string;
begin
  s := ''; // Set a breakpoint here
end;

begin
  AddExitProc(DoOnExit); // Put this line before Application.Run
  Application.Initialize;
  Application.DefaultFont.Assign(Screen.MenuFont);
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TMainForm, MainForm);
  Application.Run;
end;

Share this post


Link to post
Guest

try add that 2 sections: if all unit using it, then, we have "chain" of executions

  • same if using "HALT( code )" procedure

 

initialization

lStopHereToo := ''; // first of all

finalization

lStopHereToo := '';  // last of all

 

Edited by Guest

Share this post


Link to post
2 hours ago, shineworld said:

In BDS 2006 if I run this code and exit program first break at Form3.FormDestroy,

then breaks in main at S := ''. RIGHT !

I don't believe you!

  • Like 1

Share this post


Link to post
8 minutes ago, Attila Kovacs said:

I don't believe you!

Agreed. Why would the main form destroy itself before the code in the dpr completes?

Share this post


Link to post

You are right, I've checked again with an empty program in BDS2006 and worked as you had suggested.

But if I debug my big program the behavior is different, so there something that has changed the rules in my code!
I need to check it...

 

Thank you for the suggestion about 

 AddExitProc(DoOnExit); // Put this line before Application.Run
 

I don't know it before...

 

Share this post


Link to post
14 hours ago, shineworld said:

In BDS 2006 if I run this code and exit program first break at Form3.FormDestroy,

then breaks in main at S := ''. RIGHT !

That has NEVER been true, in ANY version...

Quote

In Sydney first, break in the main at S := '', then goes to Form3.FormDestry.

... THAT is the correct behavior, in ALL versions.

 

Auto-created Forms, like the MainForm, are owned by the Application object.  They are not destroyed until the Application object is destroyed, which is after the main DPR code is done running and the VCL is being cleaned up.

Quote

What has changed so much the Delphi behavior?

Nothing has changed. So the chance has to be something in your own code that is destroying the MainForm before the Application object is destroyed.

 

Edited by Remy Lebeau
  • Like 1

Share this post


Link to post

@Remy Lebeau

you are right,

just had to do with my project which is not good structured and something

happens in the phase of destroying objects (I guess because I'm waiting for some thread stops).

 

I've to change where objects are created and how they are freed.
Surely I've mistake some important thing 🙂

 

https://youtu.be/MNppXiVvDZI

Share this post


Link to post

I hereby want to thank all of you for the answers.
I misunderstood the mechanism of creating and destroying objects in Delphi, especially when forms are destroyed.
So far the code has worked but only because an unclosed thread changed the cards in play.

Thank you AGAIN for your time!

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×