Given there's a single type declaration,
THDItem
and that I wanted to see the field offsets as well as calculate the total size of the record, using Delphi's RTTI, I can do so with:
var rtype: TRTTIType; fields: TArray<TRTTIField>; LFieldName: string; P: Pointer; LTotalSize: Integer; LHDItem: THDItem; begin rtype := TRTTIContext.Create.GetType(TypeInfo(THDItem)); P := @LHDItem; fields := rtype.GetFields; for i := 0 to High(fields) do begin LFieldName := fields[i].Name; if LFieldName.StartsWith('placeholder', True) then Continue; WriteLn(Format('%-20s: %-10s :: %-30s, Addr: %.8x', [ LFieldName, fields[i].FieldType.ToString, fields[i].GetValue(P).ToString, fields[i].Offset])); LTotalSize := LTotalSize + fields[i].FieldType.TypeSize; end; WriteLn('Size: ', LTotalSize); end;
In 2017, with the release of Delphi 10.2 Tokyo, Embarcadero introduced a specialized implementation of the Observer pattern into the System.Classes unit. While it has been in the wild for 9 years, it remains a "hidden" architecture for many, primarily because it serves as the invisible engine behind LiveBindings. Other than live bindings, you can also use the Observer pattern as a way to update component settings to the Windows registry, an .ini file, or persist it elsewhere.
System.Classes