Avatar of Paer Toernell
Paer ToernellFlag for Thailand

asked on 

Strange behavior when a form is closed

The program have two forms, MainForm and Subform. The Mainform Button1 creates new subforms. If a few subforms is created, when they are closed (and freed) the window behind get focus, BUT not if its the mainform . Why?

unit Unit1;

interface

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

type
  TMainForm = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    List: TComponentList;
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

procedure TMainForm.Button1Click(Sender: TObject);
  Var
   T : Tform;

begin
     List.OwnsObjects:=True;
     T:=TForm2.Create(Nil);
     List.Add(T);
     T.Show;
end;

procedure TMainForm.Button2Click(Sender: TObject);
  var
    Antal : Integer;

begin
    Antal:=List.Count;
    Memo1.Lines.Add('Forms Count '+IntToStr(Antal));
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
     ReportMemoryLeaksOnShutdown:=True;
     List:= TComponentList.Create;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
    List.Free;
end;

end.

object MainForm: TMainForm
  Left = 0
  Top = 0
  Caption = 'MainForm'
  ClientHeight = 303
  ClientWidth = 641
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 32
    Top = 16
    Width = 105
    Height = 25
    Caption = 'New Window'
    TabOrder = 0
    OnClick = Button1Click
  end
  object Memo1: TMemo
    Left = 192
    Top = 16
    Width = 433
    Height = 273
    Lines.Strings = (
      'Memo1')
    TabOrder = 1
  end
  object Button2: TButton
    Left = 32
    Top = 55
    Width = 105
    Height = 25
    Caption = 'Info'
    TabOrder = 2
    OnClick = Button2Click
  end
end

unit Unit2;

interface

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

type
  TSubForm = class(TForm)
    Label1: TLabel;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  SubForm: TSubForm;

implementation

{$R *.dfm}

procedure TSubForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    Hide;
    Action := caFree;

end;

end.


object SubForm: TSubForm
  Left = 0
  Top = 0
  Caption = 'SubForm'
  ClientHeight = 299
  ClientWidth = 635
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnClose = FormClose
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 120
    Top = 48
    Width = 60
    Height = 13
    Caption = 'Second form'
  end
end

Open in new window

Delphi

Avatar of undefined
Last Comment
Paer Toernell
Avatar of Geert G
Geert G
Flag of Belgium image

because of the nil in this line :
T:=TForm2.Create(Nil);

Open in new window


it should read
T:=TForm2.Create(Self);

Open in new window


there is no point in maintaining your own Componentlist
the Screen has this property

after you have created TForm2, you can find it like this in the screen object
this routine frees all TForm2 type forms

procedure TMainForm.CloseAllForm2(Sender: TObject);
var I: Integer;
  frm: TForm2;
begin
  for I := Screen.FormCount-1 downto 0 do 
    if Screen.Forms[I] is TForm2 then 
    begin
      frm := Screen.Forms[I] as TForm2;
      frm.Free;
    end;
end;

Open in new window

Avatar of Paer Toernell

ASKER

There is need for Component list because there will be more than one class of sub-forms and the user need to be able to navigate between them. I want them to be kept separate. By a different popuplists in mainform the user will navigate.

Questoin, if I use Mainform as owner (or componentlist) wont the subforms all be destroyed when the owner is destroyed?
Avatar of Geert G
Geert G
Flag of Belgium image

you want a stay-on-top form which displays all the forms available in your app ?
you don't need an extra component to display that

if an owner is destroyed, then it first destroys all it's child components
that's just good housekeeping
ASKER CERTIFIED SOLUTION
Avatar of Geert G
Geert G
Flag of Belgium image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
Avatar of Geert G
Geert G
Flag of Belgium image

freeing a subform depends on the usage

if you would have an invoice form, with a floating form for some detail
there is no point in leaving the floating form open upon closing the invoice form
closing the floating form should not result in closing of the invoice form
Avatar of Paer Toernell

ASKER

Thanx, i added this function to extract a list of all form of a particula type, havet tested it yet but i think it will work.

procedure TfrmList.ListFormsOfType(AObjectList: TObjectList; aClass: TClass);
  Var
    I: Integer;

begin
  if AObjectList=Nil then begin
      AObjectList:=TObjectList.Create;
      AObjectList.OwnsObjects:=False;
  end;
  AObjectList.Clear;
  for I := 0 to Screen.FormCount -1 do
  Begin
    if True then
     if Screen.Forms[I] is aClass then Begin
        AObjectList.Add(Screen.Forms[I]);
     End;
  End;
end;

Open in new window

Delphi
Delphi

Delphi is the most powerful Object Pascal IDE and component library for cross-platform Native App Development with flexible Cloud services and broad IoT connectivity. It provides powerful VCL controls for Windows 10 and enables FMX development for Windows, Mac and Mobile. Delphi is your choice for ultrafast Enterprise Strong Development™. Look for increased memory for large projects, extended multi-monitor support, improved Object Inspector and much more. Delphi is 5x faster for development and deployment across multiple desktop, mobile, cloud and database platforms including 32-bit and 64-bit Windows 10.

60K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo