Recent

Author Topic: [Solved] Creating main application form at runtime  (Read 3958 times)

vejrous

  • New Member
  • *
  • Posts: 17
[Solved] Creating main application form at runtime
« on: February 05, 2018, 11:47:17 am »
Hi,
I have project where i am trying to create main application form at runtime.
Project runs, form is created, problem is after closing the form

If this is used, program does not end, but keeps running.
Code: Pascal  [Select][+][-]
  1. Form1 := TForm1.CreateNew(Application);

If this is used, memory error occures (see attachment).
Code: Pascal  [Select][+][-]
  1. Application.CreateForm(TForm1, Form1);

Form does not use resources.

Main *.lpr code:
Code: Pascal  [Select][+][-]
  1. program Test;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   Forms, Interfaces,
  7.   TestForm in 'TestForm.pas';
  8.  
  9. {$R *.res}
  10.  
  11. begin
  12.   RequireDerivedFormResource := False;
  13.   Application.Initialize;
  14.   CreateTestForm;
  15.   Application.Run;
  16. end.
  17.  

TestForm code:
Code: Pascal  [Select][+][-]
  1. unit TestForm;
  2.  
  3. {$IFDEF FPC}
  4.   {$mode objfpc}{$H+}
  5. {$ENDIF}
  6.  
  7. interface
  8.  
  9. uses
  10.   SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,
  11.   StrUtils;
  12.  
  13. type
  14.   TForm1 = class(TForm)
  15.   private
  16.     cboCommand: TComboBox;
  17.     btnRun: TButton;
  18.     mmoResult: TMemo;
  19.     procedure btnRunClick(Sender: TObject);
  20.     {$IFDEF FPC}
  21.       procedure frmClose(Sender: TObject; var CloseAction: TCloseAction);
  22.     {$ELSE}
  23.       procedure frmClose(Sender: TObject; var Action: TCloseAction);
  24.     {$ENDIF}
  25.    public
  26.     { Public declarations }
  27.     constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); override;
  28.   end;
  29.  
  30. var
  31.   Form1: TForm1;
  32.  
  33.   procedure CreateTestForm;
  34.  
  35. implementation
  36.  
  37. procedure CreateTestForm;
  38. begin
  39.   {$IFDEF FPC}
  40.      // creates memory error
  41.     Application.CreateForm(TForm1, Form1);
  42.     Form1.Show;
  43.   {$ELSE}
  44.     // delphi/under Lazarus program does not end
  45.     Form1 := TForm1.CreateNew(Application);
  46.     Form1.ShowModal;
  47.   {$ENDIF}
  48. end;
  49.  
  50. constructor TForm1.CreateNew(AOwner: TComponent; Dummy: Integer = 0);
  51. begin
  52.   inherited;
  53.  
  54.   Self.OnClose := @frmClose;
  55.  
  56.   cboCommand := TComboBox.Create(Self);
  57.   cboCommand.Parent := Self;
  58.   cboCommand.Items.Append('test command');
  59.  
  60.   btnRun := TButton.Create(Self);
  61.   btnRun.Parent := Self;
  62.   btnRun.Caption := 'Run Command';
  63.   btnRun.OnClick := @btnRunClick;
  64.  
  65.   mmoResult := TMemo.Create(Self);
  66.   mmoResult.Parent := Self;
  67.  
  68. end;
  69.  
  70. {$IFDEF FPC}
  71.   procedure TForm1.frmClose(Sender: TObject; var CloseAction: TCloseAction);
  72.         begin
  73.     CloseAction := caFree;
  74.   end;
  75. // delphi stuff
  76. {$ELSE}
  77.   procedure TForm1.frmClose(Sender: TObject; var Action: TCloseAction);
  78.   begin
  79.     Action := caFree;
  80.   end;
  81. {$ENDIF}
  82.  
  83. procedure TForm1.btnRunClick(Sender: TObject);
  84. begin
  85.   //
  86. end;
  87.  
« Last Edit: February 05, 2018, 02:37:28 pm by vejrous »

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Creating main application form at runtime
« Reply #1 on: February 05, 2018, 01:35:20 pm »
For Lazarus you have to do some variation on this:

The project's .lpr:
Code: Pascal  [Select][+][-]
  1. program ResourcelessMainForm;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  7.   cthreads,
  8.   {$ENDIF}{$ENDIF}
  9.   Interfaces, Forms, uResourcelessForm;
  10.  
  11. {$R *.res}
  12.  
  13. begin
  14.   RequireDerivedFormResource:=True;
  15.   Application.Initialize;
  16.   CreateResourcelessMainForm;
  17.   Application.Run;
  18. end.

The project's main form unit (no .lfm at all):
Code: Pascal  [Select][+][-]
  1. unit uResourcelessForm;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, Forms, StdCtrls, Controls;
  9.  
  10. type
  11.  
  12.   TResourcelessForm = class(TForm)
  13.   private
  14.     cboCommand: TComboBox;
  15.     btnRun: TButton;
  16.     mmoResult: TMemo;
  17.     procedure btnRunClick(Sender: TObject);
  18.     procedure SetupGUI;
  19.   protected
  20.     procedure DoClose(var CloseAction: TCloseAction); override;
  21.   public
  22.     constructor Create(TheOwner: TComponent); override;
  23.   end;
  24.  
  25.   procedure CreateResourcelessMainForm;
  26.  
  27. implementation
  28.  
  29. procedure CreateResourcelessMainForm;
  30. var
  31.   mainFrm: TResourcelessForm;
  32. begin
  33.   mainFrm:=TResourcelessForm.Create(Application);
  34.   mainFrm.Show;
  35. end;
  36.  
  37. { TResourcelessForm }
  38.  
  39. constructor TResourcelessForm.Create(TheOwner: TComponent);
  40. begin
  41.   inherited CreateNew(TheOwner);
  42.   Caption := 'Resourceless main form';
  43.   SetupGUI;
  44. end;
  45.  
  46. procedure TResourcelessForm.btnRunClick(Sender: TObject);
  47. begin
  48.   if cboCommand.Text <> '' then
  49.     mmoResult.Append(cboCommand.Text);
  50. end;
  51.  
  52. procedure TResourcelessForm.DoClose(var CloseAction: TCloseAction);
  53. begin
  54.   CloseAction:=caFree;
  55.   inherited DoClose(CloseAction);
  56.   Application.Terminate;
  57. end;
  58.  
  59. procedure TResourcelessForm.SetupGUI;
  60. begin
  61.   cboCommand := TComboBox.Create(Self);
  62.   with cboCommand do begin
  63.     Items.Append('test command');
  64.     AnchorSideTop.Control := Self;
  65.     AnchorSideLeft.Control := Self;
  66.     BorderSpacing.Around := 10;
  67.     Parent := Self;
  68.   end;
  69.  
  70.   btnRun := TButton.Create(Self);
  71.   with btnRun do begin
  72.     Caption := 'Run Command';
  73.     AutoSize := True;
  74.     AnchorSideTop.Control := cboCommand;
  75.     AnchorSideTop.Side := asrBottom;
  76.     AnchorSideLeft.Control := Self;
  77.     BorderSpacing.Around := 10;
  78.     OnClick := @btnRunClick;
  79.     Parent := Self;
  80.   end;
  81.  
  82.   mmoResult := TMemo.Create(Self);
  83.   with mmoResult do begin
  84.     AnchorSideTop.Control := Self;
  85.     AnchorSideLeft.Control := cboCommand;
  86.     AnchorSideLeft.Side:=asrRight;
  87.     BorderSpacing.Around := 10;
  88.     Parent := Self;
  89.   end;
  90.  
  91. end;
  92.  
  93. end.

vejrous

  • New Member
  • *
  • Posts: 17
Re: Creating main application form at runtime
« Reply #2 on: February 05, 2018, 02:36:54 pm »
@howardpc
Many thanks for help, I belive it works now.

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: [Solved] Creating main application form at runtime
« Reply #3 on: February 05, 2018, 07:19:36 pm »
Quote
If this is used, memory error occures (see attachment).
What's the matter with "0 unfreed memory blocks: 0" ???
Looks like a normal heaptrc-window to me....

This would be my first try ...  :)
Code: Pascal  [Select][+][-]
  1. PROGRAM MyMainForm;
  2. {$MODE OBJFPC}{$H+}{$J-}
  3.  
  4.  USES
  5.   Interfaces,
  6.   Forms,
  7.   uMain;
  8.  
  9. Procedure CreateMainWindow;
  10.  Begin
  11.   wndMain:= TForm.Create(Application);
  12.    Try
  13.     wndMain.ShowModal;
  14.    Finally
  15.     wndMain.Release;
  16.     wndMain:= Nil;
  17.    End;
  18.  End;
  19.  
  20. BEGIN
  21.   RequireDerivedFormResource:= True;
  22.   Application.Initialize;
  23.   CreateMainWindow;
  24. END.

Code: Pascal  [Select][+][-]
  1. UNIT uMain;
  2. {$MODE OBJFPC}{$H+}
  3.  
  4. Interface
  5.  USES
  6.   Classes, SysUtils, Forms, Controls;
  7.  
  8.  VAR
  9.   wndMain: TForm;
  10.  
  11. Implementation
  12.  
  13. END.
« Last Edit: February 05, 2018, 07:38:12 pm by RAW »
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: [Solved] Creating main application form at runtime
« Reply #4 on: February 05, 2018, 08:50:38 pm »
I recognized a weird TaskbarButton behaviour with "ShowModal".
With "Show" everything looks normal...  :)

Code: Pascal  [Select][+][-]
  1. PROGRAM MyMainForm;
  2. {$MODE OBJFPC}{$H+}{$J-}
  3.  
  4.  USES
  5.   Interfaces,
  6.   Forms,
  7.   uMain;
  8.  
  9. BEGIN
  10.  Application.Initialize;
  11.   wndMain               := TMainForm.Create(Application);
  12.    wndMain.ShowInTaskBar:= stAlways;
  13.    wndMain.Caption      := 'MainWindow';
  14.    wndMain.OnClose      := @uMain.wndMain.wndMainClose;
  15.    uMain.wndMain.wndMainSetup;
  16.    wndMain.Show;
  17.  Application.Run;
  18. END.

Code: Pascal  [Select][+][-]
  1. UNIT uMain;
  2. {$MODE OBJFPC}{$H+}{$J-}
  3.  
  4. Interface
  5.  USES
  6.   Classes, SysUtils, Forms, Controls, StdCtrls, Dialogs;
  7.  
  8.  TYPE
  9.   TMainForm = Class(TForm)
  10.    Procedure wndMainClose (Sender: TObject; Var CloseAction: TCloseAction);
  11.    Procedure MemoClick    (Sender: TObject);
  12.    Procedure wndMainSetup;
  13.  
  14.     PRIVATE
  15.      Memo: TMemo;
  16.   End;
  17.  
  18.  VAR
  19.   wndMain: TMainForm;
  20.  
  21. Implementation
  22.  
  23.  
  24. Procedure TMainForm.wndMainSetup;
  25.  Begin
  26.   Memo        := TMemo.Create(Self);
  27.   Memo.OnClick:= @MemoClick;
  28.   Memo.Parent := Self;
  29.  End;
  30.  
  31.  
  32. Procedure TMainForm.MemoClick(Sender: TObject);
  33.  Begin
  34.   ShowMessage('Memo');
  35.  End;
  36.  
  37.  
  38. Procedure TMainForm.wndMainClose(Sender: TObject; Var CloseAction: TCloseAction);
  39.  Begin
  40.   Application.Terminate;
  41.  End;
  42.  
  43. END.
« Last Edit: February 05, 2018, 10:52:03 pm by RAW »
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

vejrous

  • New Member
  • *
  • Posts: 17
Re: [Solved] Creating main application form at runtime
« Reply #5 on: February 06, 2018, 09:25:29 am »
I ques memory is ok.
Thought heaptrc window should look like this in ideal state (see attachement).

 

TinyPortal © 2005-2018