Recent

Author Topic: Form-Creation - was: manually inserted component doesn't show up  (Read 5803 times)

hy

  • Full Member
  • ***
  • Posts: 221
Form-Creation - was: manually inserted component doesn't show up
« on: September 21, 2014, 02:34:09 pm »
Hi I am creating a TRadioGroup. on the fly when required. But it doesn't show up.
code:
Code: [Select]
   rg := TRadioGroup.create(self);
   with rg do
   begin
      parent := pnlMain;
      Left := 0;
      Top := 26;
      Width := 272;
      Height := 62;
      Align := alClient;
      TabOrder := 0;
      visible := true;
   end;
I am doing (more or less) the same with TButton and it works
Code: [Select]
   btnOpt := TButton.create(self);
   with btnOpt do
   begin
      parent := pnlBtns;
      Left := 8;
      Top := 4;
      Width := 80;
      Height := 25;
      Caption := 'Options...';
      TabOrder := 0;
   end;
   
In Delphi it works ... any ideas welcome - Thanks in advance
« Last Edit: September 21, 2014, 03:56:05 pm by hy »
_____
***hy
OS: debian sid(64bit)  [fpc 3.20] Lazarus 2.0.12

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: manually inserted component doesn't show up
« Reply #1 on: September 21, 2014, 02:44:09 pm »
It's working OK here.

Make another try, removing your "Align := alClient;" instruction (or set it to another value).

With this value, the TRadioGroup is occupying all its parent area.

tr_escape

  • Sr. Member
  • ****
  • Posts: 432
  • sector name toys | respect to spectre
    • Github:
Re: manually inserted component doesn't show up
« Reply #2 on: September 21, 2014, 02:50:12 pm »
There is no problem in your code and working as well as your need.

Only i think you setted alClient i changed to alCustom...

Code: [Select]
procedure TForm1.Button1Click(Sender: TObject);
var
   rg : TRadioGroup;
begin
     rg := TRadioGroup.create(self);
   with rg do
   begin
      Name := 'rg';
      parent := pnlMain;
      caption := 'Sample groupbox';
      Left := 0;
      Top := 26;
      Width := 100;
      Height := 100;
      Align := alCustom;
      TabOrder := 0;
      visible := true;
   end;
end;

hy

  • Full Member
  • ***
  • Posts: 221
Re: manually inserted component doesn't show up
« Reply #3 on: September 21, 2014, 02:59:28 pm »
Thanks for your help!

Actually it should be align := alClient in order to cover the parent control.

Funny though: with align := alCustom it shows up - BUT it does not display the items. just the border and the caption is shown...
Any other idea?
_____
***hy
OS: debian sid(64bit)  [fpc 3.20] Lazarus 2.0.12

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: manually inserted component doesn't show up
« Reply #4 on: September 21, 2014, 03:33:26 pm »
It is pointless to set Left, Width etc. if you then set Align=alClient;
Try this code:

Code: [Select]
procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
  rg: TRadioGroup;
begin
  rg := TRadioGroup.Create(Self);
  rg.Align:=alClient;
  for i:= 0 to 3 do
    rg.Items.Add(Format('Option %d',[i]));
  rg.ItemIndex:=0;
  rg.Parent:=pnlMain;
end;

hy

  • Full Member
  • ***
  • Posts: 221
Re: manually inserted component doesn't show up
« Reply #5 on: September 21, 2014, 03:55:32 pm »
Yes, I know it's pointless setting left, width... and alClient. But I was just playing around because it didn't show up.

Problem was something different. Obviously forms are created in a different manner in Delphi and Lazarus.
I ported the form from Delphi.

the constructor of the form gets some properties
Code: [Select]
constructor TmySelection.create(aOwner : Tcomponent;
                           sMainCap, sInfo : string;
                           slitems : TStringList; iDefault : integer);
begin
   inherited create(aOwner);
{...}
end;
The radio group in question is to be inserted in the OnCreate-Event
But the onCreate-Event is NOT fired from
Code: [Select]
   inherited create(aOwner);

Instead I had to add:
Code: [Select]
constructor TmySelection.create(aOwner : Tcomponent;
                           sMainCap, sInfo : string;
                           slitems : TStringList; iDefault : integer);
begin
   inherited create(aOwner);
   {$ifdef FPC}
      self.FormCreate(AOwner);//fire OnCreate
   {$ENDIF}

{...}
end;

But the OnCreate-Event is fired AGAIN after the actual constructor and so the controls that are inserted in the OnCreate-Event twice which breaks (some?) components...

I think this is VERY strange. I assumed that such basic stuff should work in the same manner as in Delphi... )-;

In order to solve this I made a customForm with a property that holds a Variable in order to remember whether OnCreate was already fired:

Code: [Select]

constructor Tfy_CustomForm.Create(AOwner: TComponent);

begin
   _iInitState := 0;
inherited Create(AOwner);
   self.closeOnEscape := true;


   if assigned(self.OnCreate) then
      self.OnCreate(NIL);
   _iInitState := 1;
end;
And then check property in the OnCreate-Event

Code: [Select]
procedure TmySelection.FormCreate(Sender : TObject);
begin
   if (getInitState = 0) then
   begin                       
     ...
   end;
I think there must be an easier way ...
_____
***hy
OS: debian sid(64bit)  [fpc 3.20] Lazarus 2.0.12

Blaazen

  • Hero Member
  • *****
  • Posts: 3239
  • POKE 54296,15
    • Eye-Candy Controls
Re: Form-Creation - was: manually inserted component doesn't show up
« Reply #6 on: September 21, 2014, 04:06:05 pm »
Quote
Code: [Select]
constructor TmySelection.create(aOwner : Tcomponent;
                           sMainCap, sInfo : string;
                           slitems : TStringList; iDefault : integer);
begin
   inherited create(aOwner);
   {$ifdef FPC}
      self.FormCreate(AOwner);//fire OnCreate
   {$ENDIF}

{...}
end;
This code of course fires OnCreate twice.
Firing OnCreate event is managed in
Code: [Select]
inherited create(aOwner);but OnCreate must be assigned at that time.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: manually inserted component doesn't show up
« Reply #7 on: September 21, 2014, 04:12:28 pm »
Obviously forms are created in a different manner in Delphi and Lazarus.
I ported the form from Delphi.

Lazarus is compatible with Delphi as far as cross-platform considerations allow. It is far from identical.
You would have to show complete code rather than snippets to see where you are making Delphi assumptions that Lazarus perhaps does not make (if that is indeed the case).

hy

  • Full Member
  • ***
  • Posts: 221
Re: Form-Creation - was: manually inserted component doesn't show up
« Reply #8 on: September 21, 2014, 04:24:20 pm »
Ok, I broke it down into the most simple project I can think of.
I have attached the files in a zip-archive
There is a Mian-Form with one Button and onClick of the button another form is created.

The OnCreate-event is NOT FIRED on
Code: [Select]
   inherited create(aOwner);
but after the constructor has been executed

Lazarus 1.3 SVN Rev. 46237 - Debian Linux
« Last Edit: September 21, 2014, 04:44:42 pm by hy »
_____
***hy
OS: debian sid(64bit)  [fpc 3.20] Lazarus 2.0.12

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Form-Creation - was: manually inserted component doesn't show up
« Reply #9 on: September 21, 2014, 04:42:53 pm »
I'm not sure to understand what you want to do exactly, but your last sample can't work.

You get a SIGSEV because you're trying to access to your radiogroup control before it's created, in Ttestform.create.

Code: [Select]
   rg.Items.Clear;                       <-------------- bug
   if (slItems <> nil) and (slItems.count>0) then
   begin
      rg.items.AddStrings(slItems);                <-------------- bug
      rg.itemindex := iDefault;                        <-------------- bug
   end;

The constructor for your "Ttestform" form is called before the FormCreate event.
« Last Edit: September 21, 2014, 04:45:03 pm by ChrisF »

hy

  • Full Member
  • ***
  • Posts: 221
Re: Form-Creation - was: manually inserted component doesn't show up
« Reply #10 on: September 21, 2014, 04:47:11 pm »
Hello ChrisF,

that is exactly what I mean. The OnCreate-Event which creates the radiogroup is fired after the constructor and not on
Code: [Select]
inherited create(AOwner);which is the case in Delphi.
_____
***hy
OS: debian sid(64bit)  [fpc 3.20] Lazarus 2.0.12

Blaazen

  • Hero Member
  • *****
  • Posts: 3239
  • POKE 54296,15
    • Eye-Candy Controls
Re: Form-Creation - was: manually inserted component doesn't show up
« Reply #11 on: September 21, 2014, 05:09:08 pm »
I wasn't right. OnCreate is fired DoCreate which is called in AfterConstruction. The reason is that LCL is abstract framework so OnCreate is fired later.
You can try to move the code to AfterConstruction.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

rvk

  • Hero Member
  • *****
  • Posts: 6163
Re: Form-Creation - was: manually inserted component doesn't show up
« Reply #12 on: September 21, 2014, 05:09:34 pm »
that is exactly what I mean. The OnCreate-Event which creates the radiogroup is fired after the constructor and not on
Code: [Select]
inherited create(AOwner);which is the case in Delphi.
With which Delphi version are you comparing this.

Look at http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Forms_TForm_OldCreateOrder.html
There is a variable now in Delphi called OldCreateOrder (which defaults to false) when is set to true the OnCreate is run in the Create event like you say. But in the newer versions (> Delphi 3) it is called in AfterConstruction just like it is in Lazarus now.

Quote
When OldCreateOrder is false (the default) the OnCreate event occurs after all constructors are finished and the OnDestroy event occurs before any destructors are called.
« Last Edit: September 21, 2014, 05:14:10 pm by rvk »

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Form-Creation - was: manually inserted component doesn't show up
« Reply #13 on: September 21, 2014, 05:11:20 pm »
...
which is the case in Delphi.

Not for me (with an old Dephi7).

If I have one form (Form1) with one button to create the second form (Form2):
Code: [Select]
procedure TForm1.Button1Click(Sender: TObject);
var TF: TForm2;
begin
TF:=TForm2.Create(Form1);
TF.ShowModal;
end;

And this simple code for Form2:
Code: [Select]
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm2 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Déclarations privées }
  public
{ Déclarations publiques }
constructor Create(aOwner : TComponent); override;
end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

constructor TForm2.Create(aOwner : TComponent);
begin
ShowMessage('Hello1');
inherited Create(aOwner);
ShowMessage('Hello3');
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
ShowMessage('Hello2');
end;

end.

The order of the messages are: Hello1, Hello3 and finally Hello2.

Which is what I expected from the VCL/LCL. AFAIR, when a Form is created basically you have:
- create the form,
- create all its control,
- if OnCreate event (i.e. FormCreate) is present, call this event.


***Edit*** Reason explained by rvk.

.
« Last Edit: September 21, 2014, 05:16:04 pm by ChrisF »

hy

  • Full Member
  • ***
  • Posts: 221
Re: Form-Creation - was: manually inserted component doesn't show up
« Reply #14 on: September 21, 2014, 05:19:04 pm »
Thanks to all of you for clearing up the matter.
I had my projects on Borland Developer Studio 2006
All forms are actually set to OldCreateOrder := true

Now that I've understood the problem, it will be easier to convert the rest of my forms to Lazarus.

Thanks for your help
_____
***hy
OS: debian sid(64bit)  [fpc 3.20] Lazarus 2.0.12

 

TinyPortal © 2005-2018