procedure StrToSet(TypeInfo: PTypeInfo; const Value: string; out Result);
 function NextWord(var P: PChar): string;
 var I: Integer;
 begin
  while P^ in [',', ' ', '[', ']'] do Inc(P);
  I := 0; while P[I] in ['A'..'Z', 'a'..'z', '0'..'9', '_'] do Inc(I);
  SetString(Result, P, I); Inc(P, I);
 end;
type TMaxSet = set of Byte;
var
 ElemTypeInfo: PTypeInfo; ElemTypeData: PTypeData; P: PChar;
 EnumName: string; I, ElemValue: Integer;
begin
 ElemTypeInfo := GetTypeData(TypeInfo)^.CompType^;
 ElemTypeData := GetTypeData(ElemTypeInfo);
 for I := ElemTypeData^.MinValue to ElemTypeData^.MaxValue do Exclude(TMaxSet(Result), I);
 P := PChar(Value);
 repeat
  EnumName := NextWord(P);
  if EnumName = '' then Break;
  ElemValue := GetEnumValue(ElemTypeInfo, EnumName);
  if ElemValue < 0 then
   raise EConvertError.CreateFmt(SInvalidPropertyElement, [EnumName]);
  Include(TMaxSet(Result), ElemValue);
 until False;
end;