Используйте RTTI для чтения и записи перечислимого свойства как целого числа

Я знаю, как записать свойство enum в виде строки:


    var
      Form: TForm;
      LContext: TRttiContext;
      LType: TRttiType;
      LProperty: TRttiProperty;
      PropTypeInfo: PTypeInfo;
      Value: TValue;

    begin
      Form := TForm.Create(NIL);
      LContext := TRttiContext.Create;

      LType := LContext.GetType(Form.ClassType);
      for LProperty in LType.GetProperties do
        if LProperty.Name = 'FormStyle' then
        begin
          PropTypeInfo := LProperty.PropertyType.Handle;
          TValue.Make(GetEnumValue(PropTypeInfo, 'fsStayOnTop'), PropTypeInfo, Value);
          LProperty.SetValue(Form, Value);
        end;

      writeln(Integer(Form.FormStyle));  // = 3

но как установить значение, если у меня нет строки, а целое число (например, 3 для fsStayOnTop) и как читать из этого свойства, но не возвращать строку (что будет работать с Value.AsString)?


     Value := LProperty.GetValue(Obj);
     writeln(Value.AsString);  // returns fsStayOnTop but I want not a string, I want an integer
     writeln(Value.AsInteger);  // fails


person cydo    schedule 15.09.2015    source источник


Ответы (2)


Создайте TValue из порядкового номера следующим образом:

Value := TValue.FromOrdinal(PropTypeInfo, OrdinalValue);

В обратном направлении, чтобы прочитать порядковый номер, сделайте следующее:

OrdinalValue := Value.AsOrdinal;
person David Heffernan    schedule 15.09.2015

Попробуйте что-то вроде этого:

var
  Form: TForm;
  LContext: TRttiContext;
  LType: TRttiType;
  LProperty: TRttiProperty;
  Value: TValue;
begin
  Form := TForm.Create(NIL);

  LContext := TRttiContext.Create;
  LType := LContext.GetType(Form.ClassType);
  LProperty := LType.GetProperty('FormStyle');

  Value := TValue.From<TFormStyle>({fsStayOnTop}TFormStyle(3));
  LProperty.SetValue(Form, Value);

  WriteLn(Integer(Form.FormStyle));

  Value := LProperty.GetValue(Form);
  WriteLn(Integer(Value.AsType<TFormStyle>()));

  ...
end;
person Remy Lebeau    schedule 15.09.2015
comment
Зачем приводить к целому числу, а не использовать ord ()? - person David Heffernan; 15.09.2015
comment
Я пробовал нечто подобное, но у меня ничего не вышло. тоже хорошо работает, спасибо - person cydo; 17.09.2015