20

I know I have been able to do this before, long ago, so it must be possible.

I'd like to convert an item, such as a component's align property alNone, to a string that I can save, display, whatever. I know I can get the byte value and the come up with my own text, but I'm sure there is a more direct way.

For example I want to...

var S:string;
S:= somehow(Form.Align);
ShowMessage(S);

where "somehow" is however it is I convert the setting for the form's align property to a string such as "alNone'.

Wosi
  • 41,986
  • 17
  • 75
  • 82
M610
  • 225
  • 1
  • 2
  • 10

2 Answers2

27

You can convert between enum types and String back and forth using RTTI :

uses
  RTTI;

procedure TForm40.FormCreate(Sender: TObject);
var
  sAlign: string;
  eAlign: TAlign;
begin
  //Enum to string      
  sAlign := TRttiEnumerationType.GetName(Align);
 
  //string to enum
  eAlign := TRttiEnumerationType.GetValue<TAlign>(sAlign);
end;
Jens Borrisholt
  • 6,174
  • 1
  • 33
  • 67
18

Form.Align is not a value of TPersistent. It's a value of TAlign which is an enumeration type.

You can convert an enumeration value to a string with this piece of code:

type TEnumConverter = class
public
  class function EnumToInt<T>(const EnumValue: T): Integer;
  class function EnumToString<T>(EnumValue: T): string;
end;

class function TEnumConverter.EnumToInt<T>(const EnumValue: T): Integer;
begin
  Result := 0;
  Move(EnumValue, Result, sizeOf(EnumValue));
end;

class function TEnumConverter.EnumToString<T>(EnumValue: T): string;
begin
  Result := GetEnumName(TypeInfo(T), EnumToInt(EnumValue));
end;

You need to add System.TypInfo to the uses.

Do this to get Form.Align as string:

S := TEnumConverter.EnumToString(Form.Align)
Wosi
  • 41,986
  • 17
  • 75
  • 82
  • The natural follow-up question is going to be how to convert the string back to the enum value. You may as well include that in TEnumConverter, too. – Rob Kennedy Oct 30 '15 at 21:10
  • This works only for D2009 and above. For D2007 and below you should call TypInfo.GetEnumName() with the appropiate typeinfo( TEnumtype ) ) – Ritsaert Hornstra Oct 30 '15 at 21:10
  • That's what *this* code already does, @Ritsaert. Generics simply provide a convenient wrapper. The essence of the answer is to call `GetEnumName` in whatever manner your version of Delphi allows. – Rob Kennedy Oct 30 '15 at 21:12
  • This could be done via RTTI. TEnumConverter is reinventing the wheel. – Jens Borrisholt Oct 30 '15 at 21:15
  • 1
    @JensBorrisholt: Could be done with old-style RTTI, so equally well one might ask why re-invent a generic version with no upside? – MartynA Oct 30 '15 at 21:49
  • @RobKennedy: Yes, I simply state the essentials from the code. The rest is window dressing, limiting your Delphi version. Naturally having a convenient wrapper is nice but is still is... a wrapper and the question should answer how the answer is created, not focus on the wrapper in question (just my $0.02) – Ritsaert Hornstra Oct 30 '15 at 22:25
  • I didn't invent the generics version. It is already there in the RTL – Jens Borrisholt Oct 30 '15 at 22:30