Helpful Information
 
 
Category: Delphi Programming
Arrays of objects in Delphi 6

Hi,

How can you create an array of objects in Delphi 6? I want to create a 2 dimensional array (3 by 3) of labels arranged in a cube. I am making a little Tic Tac Toe game (Noughts and Crosses to you Brits) and I want to store each value in a label.

Any help would be greatly appreciated!

Regards

Tajmiester

Something like this:


var
foo: array[1..3, 1..3] of char;
bar: array[1..3, 1..3] of TLabel;
baz: array[1..3, 1..3] of TObject;

I think you get the idea ;).

Hi,

I have declared them like this but they do not appear in the object inspector and although I can get the program to run when I change one of the label's captions I can not see any difference. I thought this might be due to the fact that their default location was off the screen but when I tried to change it I got some internal CPU errors!

Are you supposed to create the labels and then declare them as an array or can you declare them and then they will just appear. Basicall I know how to code it but how do you create the objects?

Thanks

Tajmiester

I have declared them like this but they do not appear in the object inspector
The object inspector does not support arrays of labels.


when I tried to change it I got some internal CPU errors!
An array of Labels is only an array of object references, not really of labels.
Did you create and initialize the Objects themselves? The program will segfault if you access non-existent objects...


procedure TForm1.OnCreate;
var i,j:Integer
begin
for i:=1 to 3 do
for j:= 1 to 3 do begin
foo[i,j]=TLabel.Create(Self);
foo[i,j].Parent=Self; { This makes them visible }
foo[i,j].Caption:=IntToStr(i)+'/'+IntToStr(j); { example only }
end;
end;


hth,
M.

unit Unit1;

interface

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

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

var
Form1: TForm1;
TicTacToe: array[0..2,0..2] of TLabel;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var
I,J: Integer;
begin
for I:=0 to 2 do
for J:=0 to 2 do
begin
TicTacToe[I,J]:=TLabel.Create(Self);
With TicTacToe[I,J] do
begin
Left:=J*30+100;
Top:=I*30+100;
Caption:='O';
Visible:=true;
Parent:=self;
Font.Size:=16;
Font.Style:=Font.Style+[fsBold];
Font.Color:=clBlue;
end;
end;

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
I,J: Integer;
begin
for I:=0 to 2 do
for J:=0 to 2 do
TicTacToe[I,J].Free;
end;

end.


Added [ code] and [ /code] tags to make it more readable -- Scorpions4ever

DonWhit, I might be wrong, but I think you have a double-free bug.

...:=TLabel.Create(Self)

Will make the form the owner of the label and iirc components will free their owned children by thenmselves (owned, not parented). Thus you can either use TLabel.Create(nil) and Free() it yourself in the destructor or TLabel.Create(Self).

Correct me if I am wrong. It's been some time...

...M

Hi,

Thanks! It all works appart from I can't work out how to start a procedure when one of the Labels is clicked! Heres my code:



unit tic;

interface

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

type
TfrmBoard = class(TForm)
lblTitle: TLabel;
procedure FormCreate(Sender: TObject);
procedure lblTitleClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmBoard: TfrmBoard;
foo: array[1..3, 1..3] of TLabel;
implementation

{$R *.dfm}

procedure TfrmBoard.FormCreate(Sender: TObject);
var i,j:Integer;
begin
for i:=1 to 3 do
for j:= 1 to 3 do begin
foo[i,j]:=TLabel.Create(Self);
foo[i,j].Parent:=Self; { This makes them visible }
foo[i,j].Left:= (i * 40) + 80;
foo[i,j].Top:= (j * 40) + 30;
foo[i,j].Font.Size := 16;
foo[i,j].Font.Name := 'Tahoma' ;
//foo[i,j].Caption:=IntToStr(i)+'/'+IntToStr(j); { example only }
foo[i,j].Caption:=''
end;
end;


procedure TfrmBoard.foo[1,1]Click(Sender: TObject);
begin
foo[1,1].Caption:='X';
end;


end.


It tells me when I try to comiple the code that 'foo' is an undeclared identify, when I have declared it! If I can't refer to the array how should I refer to it?

I validated the above. The documentation of TComponent.Create() states that the Owner will Free() them.
Either pass "nil" as owner or don't call Free().

tajmiester:
You cannot use [] in function names. You can either replace it with:

procedure Label1_1click(Sender: TObject);
procedure Label1_2click(Sender: TObject);
...

Or you can use one generic click handler for all of them (my preferred way):

...
private:
procedure LabelClick(Sender: TObject);
...

procedure TfrmBoard.LabelClick(Sender: TObject);
begin
case (Sender as TLabel).Caption of
"1": begin
ShowMessage('The Label with Caption "1" was pressed');
end;
"2":
....
To assign this handler to an event, use eg:

Label[1,1].OnClick=LabelClick;

M.

PS: "code", not "quote" ;)

M.Hirsch is right, you don't need to free the array of objects on form close unless you do create(nil).

Hi,

I've had success implementing what's described earlier in the thread, up to that point :

Label[1,1].OnClick=LabelClick;

In my case (see the excerpt from my code here below) I've tried with

Label[1,1].OnClick=LabelClick; -> E2035 Not enough actual parameters
Label[1,1].OnClick:=LabelClick; -> E2010 Incompatible types: 'TNotifyEvent' and 'Procedure'

even with different versions such as :
Label[1,1].OnClick=LabelClick();
Label[1,1].OnClick=LabelClick(Label[1,1]);

But nothing came out.

Can someone please help me out ?? Thanks in advance !

Happens on WinXP with Turbo Delphi Explorer.

(of course I tried it with both of the bolded versions here below, but only one at a time...)



type
TForm1 = class(TForm)
...

procedure LabelClick(Sender: TObject);
procedure FormCreate(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
Box: array[1..26] of TPanel;

implementation
{$R *.dfm}

procedure TForm1.LabelClick(Sender: TObject);
begin
(Sender as TLabel).Caption := '0';
end;

Procedure Init_Boxes();
var
cnt1: integer;
begin
for cnt1:= 1 to 26 do
begin
Box[cnt1]:=TPanel.Create(nil);
Box[cnt1].OnClick:=TForm1.LabelClick;
With Box[cnt1] do
begin
Caption:=IntToStr(cnt1);
...
Parent:=Form1;
OnClick:=TForm1.LabelClick;

end;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Init_Boxes();
Form1.show;
....
end;

Amazingly enough, it's always when you've been looking for an answer for an hour, registered to a forum, spent 15 minutes putting together your infos, posted the question, that you suddently realize, just a few seconds after you hit that 'submit' button, "hey, what if I checked that too... ?".

Sorry, I used to develop with Delphi 1.... and just got back since the release of Turbo Delphi Explorer.

So earlier my statement looked like that :

Box[cnt1].OnClick:=TForm1.LabelClick;

Well ist just had to become....

Box[cnt1].OnClick:=Form1.LabelClick;

Tuuuh...

Greetings to all whom it happened... :rolleyes:

DL










privacy (GDPR)