looking for help with getting values from record to CodeSite. While i have record with basic values (int, string..) everything works okey.
But problem comes with arrays in record.
Surname : array[0..35] of WideChar
Name : array[0..25] of WideChar
(I have found this but is there any way? )
Getting type of record field with RTTI fails for static arrays
While i want to get field value of Surname / Name the TRttiField.FieldType.TypeKind is null.
Anybody knows any way how to get values of the property to string?
There is my procedure.
class procedure TCodeSite.SendObject<T>(Category: String; lObject : T; Msg: String);
var
lRTTIContext : TRttiContext;
lRTTIObjectType : TRttiType;
lRTTIField : TRttiField;
lRTTIRecordInRecord : TRttiRecordType;
lRTTIFieldInRecord : TRttiField;
lRTTIPointerType : TRttiPointerType;
lRTTIPointerValue : TValue;
lFieldName : string;
lFieldNameInRecord : string;
lStringList : TStringList;
begin
{$IfNDef CodeSiteDisabled}
if isActiveDebugCategory(Category) then
begin
lStringList := TStringList.Create;
lRTTIContext := TRttiContext.Create;
lRTTIObjectType := lRTTIContext.GetType(TypeInfo(T));
if lRTTIObjectType.TypeKind = tkRecord then
begin
for lRTTIField in lRTTIObjectType.GetFields do
begin
lFieldName := ParseFieldName(lRTTIField.ToString);
case lRTTIField.FieldType.TypeKind of
tkRecord:
begin
lRTTIRecordInRecord := lRTTIField.FieldType.AsRecord;
lStringList.Add(lFieldName);
for lRTTIFieldInRecord in lRTTIRecordInRecord.GetFields do
begin
lFieldNameInRecord := ParseFieldName(lRTTIFieldInRecord.ToString);
lStringList.Add(' '+lFieldNameInRecord +' '+GetFieldValue<T>(Addr(lObject), lRTTIFieldInRecord));
end;
end;
tkPointer:
begin
lRTTIPointerType := lRTTIField.FieldType as TRttiPointerType;
if lRTTIPointerType.ReferredType.TypeKind = tkRecord then
begin
lRTTIPointerValue := lRTTIField.GetValue(Addr(lObject));
if (not lRTTIPointerValue.IsEmpty) then
begin
for lRTTIFieldInRecord in lRTTIPointerType.ReferredType.GetFields do
begin
lStringList.Add(lFieldName + GetFieldValue<T>(Addr(lObject), lRTTIFieldInRecord));
end;
end;
end;
end
else lStringList.Add(lFieldName + ' ' + GetFieldValue<T>(Addr(lObject), lRTTIField));
end;
end;
CodeSite.Category := Category;
CodeSite.Send(Msg, lStringList);
end;
lRTTIContext.Free;
end;
{$EndIf}
end;
There is Second procedure to get value from field
class function TCodeSite.GetFieldValue<T>(const pipInstance : Pointer;
const piclField : TRttiField) : string;
begin
if not (Assigned(piclField.FieldType)) then
begin
Result := 'Pica';
Exit;
end;
case piclField.FieldType.TypeKind of
tkEnumeration : Result := BoolToStr(piclField.GetValue(pipInstance).AsBoolean);
tkFloat: Result := FloatToStr(piclField.GetValue(pipInstance).AsExtended);
tkInt64: Result := IntToStr(piclField.GetValue(pipInstance).AsInt64);
tkInteger: Result := IntToStr(piclField.GetValue(pipInstance).AsInteger);
tkString,tkUString: Result := Trim(piclField.GetValue(pipInstance).AsString);
end;
end;