Массив компонентов

=== Массив компонентов ===
Возможно ли создание массива компонентов? Для показа статуса я использую набор LED-компонентов и хотел бы иметь к ним доступ, используя массив. 
Прежде всего необходимо объявить массив:
{ 10 элементов компонентного типа TLed }
LED: array[1..10] of TLed;
При необходимости динамического создания LED-компонентов организуйте цикл, пример которого мы приводим ниже:
for counter := 1 to 10 do
begin
 LED[counter]:= TLED.Create;
 LED[counter].Top := ...
 LED[counter].Left := ...
 LED[counter].Parent := Mainform; { что-то типа этого }
end;
Если компоненты уже присутствуют на форме (в режиме проектирования), сделайте их элементами массива, например так:
leds := 0;
for counter := 0 to Form.ComponentCount do
begin
 if (Components[counter] is TLED) then
 begin
 Inc(leds);
 LED[leds] := TLED(Components[counter]);
 end
end;
Тем не менее у нас получился массив со случайным расположением LED-компонентов. Я предлагаю назначить свойству Tag каждого LED-компонента порядковый номер его расположения в массиве, а затем заполнить массив, используя это свойство:
for counter := 0 to Form.ComponentCount do
begin
 if (Components[counter] is TLED) then
 begin
 LED[Component[counter].Tag] := TLED(Components[counter]);
 end;
end;
Если вам нужен двухмерный массив, то для формирования индекса понадобится другая хитрость, например, хранение в свойстве Hint информации о времени создания компонентов. 
Source: http://delphiworld.narod.ru
ID: 00801
----
Продолжая начатую тему в "Советах по Дельфи 1.0.9" о динамическом массиве компонентов (на этот раз двухмерном, так как одномерный очень хорошо был описан в этой версии журнала) я предлагаю следующей код который позволяет создать такой массив компонентов TImage с удобным (скажем так - почти) использованием их в этом массиве (например, при осуществлении связи с каким-то другим массивом). Я использовал этот код в одной из моих программ и после многих его тестов пришёл к выводу что он нормально работает при размерах массива 17х17 (думаю что можно довести и до 20х20 и более, но это увеличило бы код... Тем более что для моей программы такого массива вполне достаточно!).
{
Листинг 1: Создание двухмерного динамического массива компонентов
© 1999, Юрий Лапицкий
}
{
Шаг №1: Вначале, сделаем потомок стандартного TImage как дополнение
для их различия в будующем массиве компонентов.
}
type
 TMyImage = class(TImage)
 private
 FXTag, FYTag: Longint;
 published
 property XTag: Longint read FXTag write FXTag default 0;
 property YTag: Longint read FYTag write FYTag default 0;
 end;
 {===================}
 {
 Шаг №2: В описание класса главной формы вставим двухмерный динамический
 массив компонентов TMyImage, а в секцию private - необходимый код для
 инициализации массива!
 }
type
 TForm1 = class(TForm)
 // Процедура реализации события OnMouseUp при наведении на картинку
 procedure ImageMouseUp(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
 public
 Images: array of array of TMyImage;
 private
 { Процедура "создания" поля }
 procedure MakeField(const MaxRows: byte = 4; MaxCols: byte = 4);
 { Процедура "убора" поля (вообще-то не обязательно,
 но я предпочитаю перестараться, чем недостараться...) }
 procedure FreeField(const MaxRows: byte = 4; MaxCols: byte = 4);
 end;
var
 Form1: TForm1;
 Bitmap1: TBitmap;
 {
 В Bitmap1 можно загрузить картинку. Например из файла Bitmap1.bmp:
 Bitmap1:=TBitmap1.Create;
 Bitmap1.LoadFromFile('Bitmap1.bmp');
 }
 {===================}
 {
 Шаг №3: Реализация процедур в секции implementation.
 }
procedure TForm1.MakeField(const MaxRows, MaxCols: byte);
var
 Col, Row: byte;
begin
 { Иницализация самого массива }
 Initialize(Images);
 System.SetLength(Images, MaxRows);
 for Row := 0 to MaxRows - 1 do
 System.SetLength(Images[Row], MaxCols);
 { Создание и заполнение элементов массива }
 for Row := 0 to MaxRows - 1 do
 for Col := 0 to MaxCols - 1 do
 begin
 Images[Row, Col] := TMyImage.Create(Self);
 with Images[Row, Col] do
 begin
 XTag := Row;
 YTag := Col;
 Picture.Bitmap := Bitmap1;
 Left := Col * Bitmap1.Width;
 Top := Row * Bitmap1.Height;
 Width := Bitmap1.Width + Left;
 Height := Bitmap1.Height + Top;
 Center := True;
 Transparent := True;
 AutoSize := True;
 Visible := True;
 onMouseUp := ImageMouseUp;
 Parent := Self;
 end
 end;
 Invalidate
end;
procedure TMainForm.FreeField(const MaxRows, MaxCols: byte);
var
 Col, Row: byte;
begin
 { Уничтожение элементов массива }
 for Row := 0 to MaxRows - 1 do
 for Col := 0 to MaxCols - 1 do
 Images[Row, Col].Destroy;
 { Уничтожение самого массива }
 Finalize(Images)
end;
procedure TMainForm.ImageMouseUp(Sender: TObject; Button:
 TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
 { Проверка необязательна, но ведь можно (случайно)
 присвоить это событие также и форме!}
 if (Sender is TMyImage) then
 begin
 {
 обратиться к элементу массива можно используя введённые
 мною дополнения: Sender.XTag и Sender.YTag
 Images[Sender.XTag, Sender.YTag]
 }
 end
end;
Source: http://delphiworld.narod.ru
ID: 00802
----
type
 PtImg = ^TtImg;
 TtImg = array [0..0] of TImage;
var
 tImg: PtImg;
GetMem(tImg, 4 * numberofentries);
Преимущество в том, что вы должны использовать столько памяти, сколько вам нужно. Недостаток в том, что вы должны кодировать все с tImg^[n].... 
Source: http://delphiworld.narod.ru
ID: 00803
----
Примечание от Vit: массивы компонентов это конечно круто, как и вообще динамические массивы, но в современных реализациях идей ООП есть и более продвинутые решения, такие как коллекции, желательно прежде чем делать динамический массив компонентов и вообще какой-либо динамический массив ознакомится например с классом TList и идеей коллекций вообще. По началу они могут вызвать у Вас чувство неудобства, особенно если вы очень привыкли к массивам, но в последующем Вы найдёте что многие типичные проблемы типа поиска, сортировки, добавления и удаления элементов, ассоциации с другими структурами, сериализация и т.п. в коллекциях уже реализованы и исключительно просты в использовании.
ID: 00804