The documentation has the answer:
By default, the ordinalities of enumerated values start from 0 and follow the sequence in which their identifiers are listed in the type declaration.
So your belief that numbering starts from one is in fact incorrect. It is the case the ord(mtFirst)=0
, ord(mtSecond)=1
and so on.
Which means your code should read:
myTypeselection := TMyType(MyRadiogroup.ItemIndex);
Because radio group indexing is also zero based.
In my own code, I use the following generic class to perform operations like this:
type
TEnumeration<T> = class
strict private
class function TypeInfo: PTypeInfo; inline; static;
class function TypeData: PTypeData; inline; static;
public
class function IsEnumeration: Boolean; static;
class function ToOrdinal(Enum: T): Integer; inline; static;
class function FromOrdinal(Value: Integer): T; inline; static;
class function MinValue: Integer; inline; static;
class function MaxValue: Integer; inline; static;
class function InRange(Value: Integer): Boolean; inline; static;
class function EnsureRange(Value: Integer): Integer; inline; static;
end;
class function TEnumeration<T>.TypeInfo: PTypeInfo;
begin
Result := System.TypeInfo(T);
end;
class function TEnumeration<T>.TypeData: PTypeData;
begin
Result := TypInfo.GetTypeData(TypeInfo);
end;
class function TEnumeration<T>.IsEnumeration: Boolean;
begin
Result := TypeInfo.Kind=tkEnumeration;
end;
class function TEnumeration<T>.ToOrdinal(Enum: T): Integer;
begin
Assert(IsEnumeration);
Assert(SizeOf(Enum)<=SizeOf(Result));
Result := 0;
Move(Enum, Result, SizeOf(Enum));
Assert(InRange(Result));
end;
class function TEnumeration<T>.FromOrdinal(Value: Integer): T;
begin
Assert(IsEnumeration);
Assert(InRange(Value));
Assert(SizeOf(Result)<=SizeOf(Value));
Move(Value, Result, SizeOf(Result));
end;
class function TEnumeration<T>.MinValue: Integer;
begin
Assert(IsEnumeration);
Result := TypeData.MinValue;
end;
class function TEnumeration<T>.MaxValue: Integer;
begin
Assert(IsEnumeration);
Result := TypeData.MaxValue;
end;
class function TEnumeration<T>.InRange(Value: Integer): Boolean;
var
ptd: PTypeData;
begin
Assert(IsEnumeration);
ptd := TypeData;
Result := Math.InRange(Value, ptd.MinValue, ptd.MaxValue);
end;
class function TEnumeration<T>.EnsureRange(Value: Integer): Integer;
var
ptd: PTypeData;
begin
Assert(IsEnumeration);
ptd := TypeData;
Result := Math.EnsureRange(Value, ptd.MinValue, ptd.MaxValue);
end;
With that at hand your code becomes:
myTypeselection := TEnumeration<TMyType>.FromOrdinal(MyRadiogroup.ItemIndex);