»  The Delphi Column 

  ENUMERATIONS

In this column, we have a detailed look at ENUMERATIONS in Delphi.

An enumerated variable contains one value out of a list that was defined previously in the corresponding type declaration.

The Delphi Visual Component Library uses enumerated types in many places. For example, the position of a form is defined as follows:

type
TPosition = (poDesigned, poDefault, poDefaultPosOnly, poDefaultSizeOnly, poScreenCenter, poDesktopCenter, poMainFormCenter, poOwnerFormCenter);

In the Object Inspector, you use Position to set the size and placement of a form.

Enumerated Types

An enumerated type is just a shorthand way of assigning sequential values to constants. An enumerated type defines an ordered set of values. The values themselves have no inherent meaning, they act only as "labels".

To declare an enumerated type, use the syntax:

type TypeName = (Val1, Val2, ..., Valn);

where each Val is a constant of type TypeName. For example, the declaration:

type TDirection = (dirNorth, dirEast, dirSouth, dirWest);

defines an enumerated type called TDirection, whose possible values are dirNorth, dirEast, dirSouth, dirWest; and where Ord(dirNorth) returns 0, Ord(dirEast) returns 1, and so on.

Subrange Types

A subrange type represents a subset of the values in another ordinal type.

A construction of the form "Low..High", where Low and High are constant expressions of the same ordinal type and Low is less than High, identifies a subrange type that includes all the values from Low to High. For example, if you declare the enumerated type:

type TColors = (Red, Blue, Green, Yellow, Orange, Purple, White, Black);

you can then define a subrange type like:

type TMyColors = Green..White;

Here TMyColors includes the values Green, Yellow, Orange, Purple, and White.

For... To loop with enumerated variable

Delphi allows us to work with the elements of an enumerated type using an index that comes from the order that they were listed in. In the following example, dirNorth in the dirNorth type declaration has the index 0, dirEast has the index 1, and so on. Now you can write something like:

procedure TForm1.Button1Click(Sender: TObject);
type
  dirNorth = (dirNorth, dirEast, dirSouth, dirWest);
var
  Dir: TDirection;
begin
  for Dir := dirNorth to dirWest do
    ShowMessage('Ordinality: ' + IntToStr(Ord(Dir)));
end;

Pitfalls

1. It's best to choose constant names that are not likely to conflict with other identifiers. Examples:

type TSound = (tsClick, tsClack, tsClock); TMyColor = (mcRed, mcBlue, mcGreen, mcYellow, mcOrange); TAnswer = (ansYes, ansNo);

You can use the (Val1, ..., Valn) construction directly in variable declarations, as if it were a type name:

var Dir1: (dirNorth, dirEast, dirSouth, dirWest);

But if you declare Dir1 this way, you can not use the keyword var again to declare another enumerated variable with the same constant identifiers. Thus:

var Dir1: (dirNorth, dirEast, dirSouth, dirWest); var Dir2: (dirNorth, dirEast, dirSouth, dirWest);

generates a compilation error. But:

var Dir1, Dir2: (dirNorth, dirEast, dirSouth, dirWest);

compiles fine. Also the following causes no error:

type TDirection = (dirNorth, dirEast, dirSouth, dirWest); var Dir1: TDirection; Dir2: TDirection;

2. The use of constant expressions in subrange definitions introduces a syntactic difficulty. In a type declaration, when the first meaningful character after = is a left parenthesis, the Delphi compiler assumes that you are defining an enumerated type. Hence the code:

const X = 50; Y = 10; type TScale = (X - Y) * 2..(X + Y) * 2;

produces an error. Work around this problem by rewriting the code, move the first parenthesis more to the right:

type Scale = 2 * (X - Y)..(X + Y) * 2;


Database Tutorials  FAQ  Crash Course Delphi  Tips  Source Code  Downloads  Links

© Copyright 1999-2019 
DelphiLand