Re: Delphi: Changing properties of all components


[ Related Articles and Replies ] [ DelphiLand Discussion Forum ]

Posted by webmaster Guido on March 15, 2002:

In Reply to: Changing properties of all components posted by Jeroen Beenes on March 11, 2002:

: Onder het menu 'Broncode' staat een voorbeeld voor het wijzigen van de properties van alle componenten van een bepaald type. Kan ik ook de properties wijzigen van alle componenten die ik in mijn applicatie heb??? Dus zonder een bepaald type aan te geven????
--------

Translation:

:In the section "Code Snips", there's an example for changing the properties of all components of a certain type. Can I also change the properties of all the components of my application? Can I do this, without indicating a certain type?
-------

Let's analyze the example that you are referring to:

procedure TForm1.SetEditsColor(NewColor: TColor);
var
  i: integer;
begin  
  for i := 0 to ComponentCount - 1 do
    if Components[i] is TEdit then
      TEdit(Components[i]).Color := NewColor;
end;

ComponentCount is the number of components owned by a container-component (a component that containes other components), and Components is the array that holds pointers to these components.
Because nothing is specified in front of ComponentCount, it is the same as writing Self.ComponentCount, where Self refers to the form. So "ComponentCount" is the number of components owned by Form1. Likewise, Components is in fact Self.Components, so it is the array that holds pointers to the components that are on Form1.

Delphi is very strict when it comes to type compatibility. The elements of the array Components are of the type TComponent. And because the type TComponent has no property Color, we are not allowed to write:

Components[i].Color := ...

TEdit inherits its property "color" from TCustomEdit, which inherits it from TWinControl, which inherits it from TControl, the class where "color" is defined. TControl comes from TComponent (you can look up this hierachy in Delphi's Help).

But we use a trick: we typecast some elements of Components[i] as a TEdit, in other words: we tell Delphi to "treat them as" a TEdit, not simply as a TComponent. That's done with TEdit(). By the way, you may also use the equivalent as TEdit. In the example we could write:

(Components[i] as TEdit).Color := NewColor;

Very important: we need the part that says:

if Components[i] is TEdit then
...because not all components can be typecasted as a TEdit. For example, you may not "treat" a TLabel as a TEdit, because TLabels and TEdits descend from quite different branches in Delphi's tree of objects.

So, can you write code to change the properties of all the components of a form? Yes. Can you do that for all the components of an application? Yes, by repeating that same routine for each of the application's forms. Can you do this without referring to the types of the components? No.

An example: say, you want to change the font-color of all the TLabel, all the TEdit and all the TBitBtn components of a form to red:

for i := 0 to ComponentCount - 1 do begin
  if Components[i] is TLabel then
    TLabel(Components[i]).Font.Color := clRed
  else if Components[i] is TEdit then
    TEdit(Components[i]).Font.Color := clRed
  else if Components[i] is TBitBtn then
    TBitBtn(Components[i]).Font.Color := clRed;
end;

================================

ComponentCount is de property die het aantal componenten aangeeft, waarvan een "container-component" eigenaar is (een component die andere componenten bevat, zoals bijvoorbeeld een TForm). Components is een array die "pointers" (wijzers) bevat naar deze componenten.
Omdat er niets *voor* ComponentCount staat, betekent dit in feite Self.ComponentCount, waarbij Self hier verwijst naar de form. ComponentCount is dus het aantal componenten van Form1. Zo betekent Components in feite Self.Components, dus de array met pointers naar alle componenten die "op Form1 zitten".

Delphi is heel strikt als het aankomt op type-compatibiliteit. De elementen van de array Components zijn van het type TComponent. En omdat het type TComponent geen property Color kent, mogen we niet schrijven:

Components[i].Color := ...

TEdit erft zijn property "color" van TCustomEdit, die het erft van TWinControl, die het op zijn beurt erft van TControl, de class waar "color" gedefineerd wordt. TControl komt van TComponent. Die stamboom kan je vinden in de Help van Delphi.

Daarom gebruiken we de volgende truuk: we typecasten sommmige elementen van Components[i] als TEdit, m.a.w.: we zeggen tegen Delphi dat ie ze moet "behandelen als" TEdit, niet gewoonweg als TComponent. Dat doe je met TEdit(). Je mag overigens ook het equivalente as TEdit gebruiken, in het voorbeeld wordt dat dan:

(Components[i] as TEdit).Color := NewColor;

Nu, om te beginnen kunnen we niet zonder deze code:

if Components[i] is TEdit then
...want niet alle componenten mag je zomaar typecasten als een TEdit. Zo kan je bijvoorbeeld een TLabel niet "behandelen als" een TEdit, omdat TLabels en TEdits afstammen van heel verschillende takken van Delphi's objecten-boom.

Dus om te antwoorden op je vragen: kan je code schrijven die de properties wijzigt van alle componenten van een form? Ja. Kan dat ook voor alle componenten van een applicatie? Ja, als je het herhaalt voor alle forms van de applicatie. Gaat het zonder ergens aan te geven om welk type van componenten het gaat? Nee.

Onderaan mijn engelstalige uitleg staat een voorbeeldje van hoe je de font-kleur wijzigt van alle TLabel, TEdit en TBitBtn componenten van een form.


Related Articles and Replies:


[ Related Articles and Replies ] [ DelphiLand Discussion Forum ]