I am using Delphi 6 Professional. I am interfacing with a DLL libraty that declares an enumberated type as follows:
TExtDllEnum = (ENUM1 = $0, ENUM2 = $1, ENUM3 = $2, ENUM4 = $4, ENUM5 = $8, ENUM6 = $10);
As you can see the initialized values are not contiguous. If I try to iterate the type using a for loop as follows:
var
e: TExtDllEnum;
begin
for e := Low(TExtToDllEnum) to High(TExtToDllEnum) do
... // More code
end;
Delphi still increments e by 1 each loop invocation and thereby creates numeric values for e that are not members of the enumerated type (for example, '3'), and resulting in an 'out of bounds' error. How can I iterate the enumerated type in a for loop that generates only valid values for the enumerated type?
Thanks.
By defining a set of constants...
type
TExtDllEnum = (ENUM1 = $0, ENUM2 = $1, ENUM3 = $2, ENUM4 = $4, ENUM5 = $8, ENUM6 = $10);
const
CExtDllEnumSet = [ENUM1, ENUM2, ENUM3, ENUM4, ENUM5, ENUM6];
var
e: TExtDllEnum;
begin
e := Low(TExtDllEnum);
while e <= High(TExtDllEnum) do
begin
if e in CExtDllEnumSet then
WriteLn(Ord(e));
Inc(e);
end;
ReadLn;
end.
and implemented as an iterator - just for fun...
type
TExtDllEnum = (ENUM1 = $0, ENUM2 = $1, ENUM3 = $2, ENUM4 = $4, ENUM5 = $8, ENUM6 = $10);
const
CExtDllEnumSet = [ENUM1, ENUM2, ENUM3, ENUM4, ENUM5, ENUM6];
type
TMyIterator = class
private
FValue: TExtDllEnum;
public
constructor Create;
function Next: TExtDllEnum;
function HasNext: Boolean;
end;
constructor TMyIterator.Create;
begin
FValue := Low(TExtDllEnum);
end;
function TMyIterator.HasNext: Boolean;
begin
Result := FValue <= High(TExtDllEnum);
end;
function TMyIterator.Next: TExtDllEnum;
begin
Result := FValue;
repeat
Inc(FValue);
until (FValue in CExtDllEnumSet) or (FValue > High(TExtDllEnum))
end;
var
MyIterator: TMyIterator;
begin
MyIterator := TMyIterator.Create;
while MyIterator.HasNext do
WriteLn(Ord(MyIterator.Next));
MyIterator.Free;
ReadLn;
end.
As far as I can remember, there's no way to iterate the way you want. If the enumeration is not changed frequently, a workaround may be to declare a "index array", which let you iterate the way you want. The trick is you don't iterate over the enumeration, but over a index which you can in turn "convert" to a valid element in the enum:
I think I can explain the idea better in code:
const
ExtDllEnumElements = 6;
EnumIndexArray: array[0..ExtDllEnumElements - 1] of TExtDllEnum = (ENUM1, ENUM2, ENUM3, ENUM4, ENUM5, ENUM6);
var
I: Integer;
begin
for I := Low(EnumIndexArray) to High(EnumIndexArray) do
WhateverYouWantWith(EnumIndexArray[I]);
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With