I can reproduce the issue. Interestingly, if you don't use the TRttiContext and just assign the ColorProp directly to the TValue then TValue.ToString() works as expected:
//Val := AColorProp.GetValue(ColorObj);
Val := ColorObj.ColorProp; // Val.ToString now returns '4294303411'
In both cases, the numeric value (inside the TValue.FAsULong field) is correct, but the RTTI for the value different - in the first case, the TValue.FTypeInfo belongs to TAlphaColor, but in the second case the TValue.FTypeInfo belongs to Cardinal instead!
Both RTTIs have Kind=tkInteger and OrdType=otULong, so the numeric value is stored in TValue.FAsULong and TValue.ToString() formats as a UInt64. But, the TValue.AsUInt64 property getter behaves differently on the two RTTI types:
function TValue.AsUInt64: UInt64;
begin
if not IsEmpty then
begin
if FTypeInfo = System.TypeInfo(Int64) then
Exit(FAsSInt64)
else if FTypeInfo = System.TypeInfo(UInt64) then
Exit(FAsUInt64)
else if FTypeInfo = System.TypeInfo(Cardinal) then
Exit(FAsULong) // <-- SECOND CASE
else if FTypeInfo^.Kind = tkInteger then
Exit(AsInteger); // <-- FIRST CASE
end;
AsTypeInternal(Result, System.TypeInfo(UInt64));
end;
function TValue.AsInteger: Integer;
begin
if not IsEmpty then
begin
if FTypeInfo = System.TypeInfo(Integer) then
Exit(FAsSLong)
else if FTypeInfo^.Kind = tkInteger then
case GetTypeData(FTypeInfo)^.OrdType of
otSByte: Exit(FAsSByte);
otSWord: Exit(FAsSWord);
otSLong: Exit(FAsSLong);
else
Exit(FAsULong); // <-- FIRST CASE
end;
end;
AsTypeInternal(Result, System.TypeInfo(Integer));
end;
In the first case, TValue.FTypeInfo does not belong to either UInt64 or Cardinal (it belongs to TAlphaColor), so the TValue.FAsULong field (whose unsigned value is 4294303411, hex $FFF5DEB3) first gets converted to a signed Integer, resulting in a negative value of -663885 (hex $FFF5DEB3), which is then converted up to a sign-extended UInt64, resulting in a large unsigned value of 18446744073708887731 (hex $FFFFFFFFFFF5DEB3).
In the second case, the TValue.FTypeInfo belongs to Cardinal (an unsigned type), so the TValue.FAsUlong field (hex $FFF5DEB3) is converted as-is to a zero-extended UInt64, preserving the original value (hex $00000000FFF5DEB3).