Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 5 of 5 total
Thread error when trying to create buttons on a panel
Sun, Feb 26 2017 12:07 PMPermanent Link

kamran

Hi

Here is my code:

  private
     { Private declarations }
     MenuButtons:TObjectList;
     procedure InitialiseObjects;
     procedure FreeObjects;
     procedure CreateButtons;

.....

procedure TMenuFrm.CreateButtons;
var
  i: integer;
  NewButton: TButton;
begin
  for i := 0 to 5 do
  begin
     begin
        NewButton := TButton.Create(NewButton);
        NewButton.Caption:='Menu Button';
        MenuButtons.Add(NewButton);  <-------------------------------- i think it fails here !!!!
        with NewButton do
        begin
          Layout.Consumption:=lcRight;
          Layout.Consumption:=lcRight;
          Layout.Overflow:=loBottom;
          Background.Fill.Color:=clWhite;
          Name:='Menu Button'+IntToStr(i);
          Width:=100;
          Height:=100;
          if i <= 2 then Top:=(300 * i);
          if i <= 2 then Left:=0;
          if i > 2 then Left:=100;
          if i > 2 then Top:=(300 * i) - 300;
          Parent:=HeaderMenuPanel;
          AlwaysOnTop:=True;
          Visible:=True;
          Enabled:=True;
        end;
     end;

  end;
end;

The error I  get when calling procedure CreateButtons


is "unable to property of 'add' of undefined or null reference" line xxxx

It looks right ... but not sure why it does not like the add.

Thanks

Kamran
Sun, Feb 26 2017 12:41 PMPermanent Link

Uli Becker

Kamran,

that looks a bit messy Smile

First of all you have to create the ObjectList (and free it with the
form) before using it:
MenuButtons := TObjectList.create;

NewButton := TButton.Create(NewButton);
Should be
NewButton := TButton.Create(HeaderMenuPanel); // Parent AND Owner =
HeaderMenuPanel

Then you can skip:
Parent:=HeaderMenuPanel;
Visible:=True; // By Default
Enabled:=True; // By Default

You assign some layout properties but don't use them:
Layout.Consumption:=lcRight;
Layout.Consumption:=lcRight;

is defined twice, but no LayoutPosition!

 if i <= 2 then Top:=(300 * i);
 if i <= 2 then Left:=0;
 if i > 2 then Left:=100;
 if i > 2 then Top:=(300 * i) - 300;

Doesn't make sense if you use layouts (what I'd recommend!)

Show me a panel with buttons as you want it to look like and I can help
you with the layout properties.

Uli

Sun, Feb 26 2017 2:02 PMPermanent Link

kamran

Hi Uli

Thanks for the tips.. I have modified my code as follows..

......................................................

procedure TMenuFrm.CreateButtons;
var
  i: integer;
  NewButton: TButton;
  BtnLeft,BtnTop,BtnWidth,BtnHeight,BtnSpacer:Integer;
  MenuID:string;
begin
// set the button sizes
BtnLeft:=5;
BtnTop:=5;
BtnWidth:=170;
BtnHeight:=90;
BtnSpacer:=100;

MenuButtons:=TObjectList.Create(true);
MenuButtons.Free;

MenuID:=TIAMODataFrm.Menu.columns['menu_id'].asString;
TIAMODataFrm.MenuHeader.First;
while not TIAMODataFrm.MenuHeader.eof do
begin
if TIAMODataFrm.MenuHeader.columns['menu_id'].asString = MenuID then
begin
   NewButton := TButton.Create(HeaderMenuPanel);
   MenuButtons.Add(NewButton);
   with NewButton do
   begin
      left:=BtnLeft;
      top:=BtnTop;
      width:=BtnWidth;
      height:=BtnHeight;
      caption:=TIAMODataFrm.MenuHeader.columns['menuheader_name'].asString;
   end;
   BtnTop:=BtnTop+BtnSpacer;
end;
TIAMODataFrm.MenuHeader.Next;
end;

end;
..............................................

The first time I call CreateButtons,  it shows the buttons correctly with the menu captions as expected.

The problem I now have is  that the second time I call CreateButtons (with another menu_id)  it DOES NOT clear the old buttons and captions as  I would have expected it too.

Any ideas ?

Cheers

Kamran

Uli Becker wrote:

Kamran,

that looks a bit messy Smile

First of all you have to create the ObjectList (and free it with the
form) before using it:
MenuButtons := TObjectList.create;

NewButton := TButton.Create(NewButton);
Should be
NewButton := TButton.Create(HeaderMenuPanel); // Parent AND Owner =
HeaderMenuPanel

Then you can skip:
Parent:=HeaderMenuPanel;
Visible:=True; // By Default
Enabled:=True; // By Default

You assign some layout properties but don't use them:
Layout.Consumption:=lcRight;
Layout.Consumption:=lcRight;

is defined twice, but no LayoutPosition!

 if i <= 2 then Top:=(300 * i);
 if i <= 2 then Left:=0;
 if i > 2 then Left:=100;
 if i > 2 then Top:=(300 * i) - 300;

Doesn't make sense if you use layouts (what I'd recommend!)

Show me a panel with buttons as you want it to look like and I can help
you with the layout properties.

Uli
Mon, Feb 27 2017 2:41 AMPermanent Link

Uli Becker

There are still some parts in your code which don't make sense:

> MenuButtons:=TObjectList.Create(true);
> MenuButtons.Free;

You create the ObjectList and free it just after creating???
What I suggested in my last post was to free the ObjectList when
destroying the form.

> The problem I now have is  that the second time I call CreateButtons (with another menu_id)  it DOES NOT clear the old buttons and captions as  I would have expected it too.

You expect the "old" buttons to free themselves?
Off course you have to free them in code before populating the panel again:

for i := HeaderMenuPanel.ControlCount-1 downto 0 do
   if HeaderMenuPanel.Controls[i] is TButton then
      HeaderMenuPanel.Controls[i].free;

Uli      
Mon, Feb 27 2017 6:29 AMPermanent Link

kamran

Thanks for that Uli

Uli Becker wrote:

There are still some parts in your code which don't make sense:

> MenuButtons:=TObjectList.Create(true);
> MenuButtons.Free;

You create the ObjectList and free it just after creating???
What I suggested in my last post was to free the ObjectList when
destroying the form.

> The problem I now have is  that the second time I call CreateButtons (with another menu_id)  it DOES NOT clear the old buttons and captions as  I would have expected it too.

You expect the "old" buttons to free themselves?
Off course you have to free them in code before populating the panel again:

for i := HeaderMenuPanel.ControlCount-1 downto 0 do
   if HeaderMenuPanel.Controls[i] is TButton then
      HeaderMenuPanel.Controls[i].free;

Uli
Image