2

I am writing a program that uses many shapes and I need to create a procedure to turn them all white. The shapes in question are named SectorBorder1 to SectorBorder20.

Is there a way to adress the shapes like this or similarly?

SectorBorder[X].brush.color := ClWhite;
Inc(X);

...where X is the number (obviously), instead of having to do:

SectorBorder1.brush.color := ClWhite;
SectorBorder2.brush.color := ClWhite;
...
SectorBorder20.brush.color := ClWhite;

So basically being able to differentiate names through a variable. This is the only way I could think of describing it. (Sorry, could someone also maybe include a better discription?) Any advice would be greatly apreciated.

1
  • You can use an array for this. Or a list. Commented Apr 28, 2021 at 13:34

3 Answers 3

4

Use an array

private
  SectorBorders: array[1..20] of TShape;

procedure TMyForm.FormCreate(Sender: TObject):
begin
  SectorBorders[1] := SectorBorder1;
  ..
  SectorBorders[20] := SectorBorder20;
end;

procedure TMyForm.SetAllToWhite;
var
  X: Integer;
begin
  for X := Low(SectorBorders) to High(SectorBorders) do
    SectorBorders[X].Brush.Color := clWhite;
end;
Sign up to request clarification or add additional context in comments.

Comments

1

As an alternative to an array you can use a List. If you use the TList from System.Generics.Containers you can easily pass through all elements of the list.

You use it like this:

interface

uses  System.Generics.Collections;   // you need this to get the TList, you also need your other refereces of course

  ...

  protected
    pShapes:  TList<TShape>;

  procedure TMyForm.FormCreate(Sender: TObject):
  var
    nLoop: Integer;
  begin
    Self.pShapes:=TList<TShape>.Create;
    nLoop:=0;
    while(nLoop<Self.ComponentCount) do
    begin
      if(Self.Components[nLoop] is TShape) then
        pList.Add(TShape(Self.Components[nLoop]));
      Inc(nLoop);
    end;
  end;

  procedure TMyForm.SetAllToWhite;
  var
    pShape:  TShape;
  begin
    for pShape in Self.pShapes do 
      pShape.Brush.Color := clWhite;
  end;

Choosing whether you want to use an array or a TList will be partially down to preference, but also down to what else you may want to do with the collection of TShapes and how they are managed within the object.

Comments

1

You can use the FindComponent method of the form.

shape:= FindComponent('SectorBorder' + IntToStr(i)) as TShape;
if shape <> nil then 
   pShape.Brush.Color := clWhite;

See http://docwiki.embarcadero.com/CodeExamples/Sydney/en/FindComponent_(Delphi)

3 Comments

Please beware, that if you have a non-TShape component named "SectorBorder99" you'll get an exception at the "as" stage. Safer to first find the component and then check (using "is") if the component you have found is a TShape (or child thereof).
Also, in most cases, FindComponent (and referring to components by string names in general) is an antipattern.
Yes - you risk a later developer coming in and renaming/making a new component that suddenly makes your program crash due to an assumption you've put in that (s)he wasn't aware of.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.