Tutorials - Creating Arrays of Objects at Design time

'

Introduction

This is a question I see asked a great deal on the newsgroups: In Visual Basic I can create Arrays of objects at design time, how is this done in Delphi? The fact of the matter is that you cannot, but you can cheat and create the array in your code which is what I am going to explain how do here.

Why use an Array?

When you need to perform the same action on a lot of controls it is quicker to code, and easier to read and maintain if you can loop through all the controls and perform your desired action on them. An example of doing it with out an array would be:
	Button1.hide;
	Button2.hide;
	Button3.hide;
	Button4.hide;
	Button5.hide;
	Button6.hide;
	.............

Whilst if these were stored in an array you would just need:

	for iTemp := 1 to 10 do
		ButtonArray[iTemp].visible := True;

A case where this maybe useful is if you have an entry form with a lot of checkboxes, and you wish to give the user a reset button which would uncheck all the boxes. You could just loop through all the components on the form looking for checkboxes, but if some did not need to respond to the reset then this may not be feasible.

Getting Started

What we need to do first is declare our array in the unit that contains the form with the controls that we wish to reference. In the example I am using TButtons so the declaration is done like this:
	ButtonArray : array [1..10] of TButton;
A point to note here is that just because we have created an Array of TButton, the buttons themselves have not been created, just pointers to them.

Next we need to place the required controls (TButtonþs) on the Form. In this example I placed ten Buttons on the form and kept with the default names as this made them easier to search for and add to the array later.

Finally in this section we need to make our array of buttons point to those that we placed on the form. This is do in the FormCreate event by:
procedure TForm1.FormCreate(Sender: TObject);
  var  iTemp1 : Integer;
      iTemp2 : Integer;
begin
  { Loop through all the buttons to add to the array }
  for iTemp1 := 1 to 10 do
  begin
    { Loop through all controls on the form looking for 
	  the buttons we wish to add }
    for iTemp2 := 0 to ComponentCount-1 do
    begin
      if (Components[iTemp2].Name = 
	      'Button'+inttostr(iTemp1)) then
      begin
        { It must be a button so can cast it safely }
        ButtonArray[iTemp1] := TButton(Components[iTemp2]);
      end;
    end; // for all components
  end; // for all buttons
end;
All this procedure does is for each element in the array, look for the component with the required name (e.g. Button6) and then make that element in the array point to that button. If you have used more meaningful button names then you would need to fill the array by:
  ButtonArray[1] := NewButton;
  ButtonArray[2] := SaveButton;
  ButtonArray[3] := LoadButton;
  .... etc.

Using the Array

Now that we have all the buttons referenced in the array all we need to do to access all of them is to loop through them. In this example I added two two more buttons to the form, one called ShowAll and the other HideAll. And assigned the onClick event of both of buttons to these respective examples:
    procedure TForm1.HideAllClick(Sender: TObject);
    var
        iTemp : Integer;
    begin
        { Loop through all the buttons and hide them }
        for iTemp := 1 to 10 do
            ButtonArray[iTemp].visible := False;
    end;
procedure
TForm1.ShowAllClick(Sender: TObject); var iTemp : Integer; begin { Loop through all the buttons and show them } for iTemp := 1 to 10 do ButtonArray[iTemp].visible := True; end;
As can be seen from the code when the ShowAll button is clicked all the buttons in the array have there visible property set to true. whilst the HideAll does the opposite. This is a very simple example but I hope it shows how much easier it is to do it this way.

Cleaning Up

As all the buttons were created at design time using the IDE and Object Inspector they will be destroyed by their owner (the form) when that is destroyed. Therefore we do not to destroy them as the array only points at them. So there is no cleaning up to be done.

Conclusion

I have tried to keep this article and respective example as clean (the minimum of code) and simple as possible. In real life you would probably be using a lot more complex code in the loops. I hope this is enough to get you started. If you find that you are looping through the array often you may find it easier to use callbacks on which I have already written an article.
Google
Web www.Delphi-Central.com
Delphi Central - Delphi Programming Tutorials, Hints and Tips