Soooo...
Letztendlich war das Object Copy verantwortlich. Warum auch immer.
Egal wie ich es umgestellt habe, die Zugriffsverletzung kam dann an anderer Stelle.
Sollte man das Bug betrachten?
Ich habe eine ObjectCopy hier gefunden...
https://delphihaven.wordpress.com/20...ng-using-rtti/ und für mich angepaßt. Damit wird das Object, ohne Speicherfehler, kopiert. Mein MessageDialog war nicht die Ursache.
Diese basiert auf der
RTTI und nicht auf Marshall/Unmarshall.
Wobei ich davon ausgehe, daß REST/DBX JSON auch die
RTTI benutzt. Oder?
Delphi-Quellcode:
unit ObjectClone;
interface
type
TObjectClone =
record
class function From<T:
class>(Source: T): T;
static;
end;
implementation
uses
SysUtils, Classes, TypInfo,
RTTI, Controls;
class function TObjectClone.From<T>(Source: T): T;
var
Context: TRttiContext;
IsComponent, LookOutForNameProp: Boolean;
RttiType: TRttiType;
Method: TRttiMethod;
MinVisibility: TMemberVisibility;
Params: TArray<TRttiParameter>;
Prop: TRttiProperty;
SourceAsPointer, ResultAsPointer: Pointer;
begin
RttiType := Context.GetType(Source.ClassType);
//find a suitable constructor, though treat components specially
IsComponent := (Source
is TComponent);
for Method
in RttiType.GetMethods
do
if Method.IsConstructor
then
begin
Params := Method.GetParameters;
if Params =
nil then Break;
if (Length(Params) = 1)
and IsComponent
and
(Params[0].ParamType
is TRttiInstanceType)
and
SameText(Method.
Name, '
Create')
then Break;
end;
if Params =
nil then
Result := Method.Invoke(Source.ClassType, []).AsType<T>
else
Result := Method.Invoke(Source.ClassType, [TComponent(Source).Owner]).AsType<T>;
try
//many VCL control properties require the Parent property to be set first
if Source
is TControl
then TControl(Result).Parent := TControl(Source).Parent;
//loop through the props, copying values across for ones that are read/write
Move(Source, SourceAsPointer, SizeOf(Pointer));
Move(Result, ResultAsPointer, SizeOf(Pointer));
LookOutForNameProp := IsComponent
and (TComponent(Source).Owner <>
nil);
if IsComponent
then
MinVisibility := mvPublished
//an alternative is to build an exception list
else
MinVisibility := mvPublic;
for Prop
in RttiType.GetProperties
do
if (Prop.Visibility >= MinVisibility)
and Prop.IsReadable
and Prop.IsWritable
then
if LookOutForNameProp
and (Prop.
Name = '
Name')
and
(Prop.PropertyType
is TRttiStringType)
then
LookOutForNameProp := False
else
Prop.SetValue(ResultAsPointer, Prop.GetValue(SourceAsPointer));
except
Result.Free;
raise;
end;
end;
end.
@freimatz:
Zitat:
Warum hat TDocumentProperties so viele properties die nichts machen? Warum nicht gleich ein record? (KISS)
...weil Records nicht vererbbar sind und nicht in TObjectList<> liegen können.
Zitat:
Warum hat die Klasse auch Methoden?
...wie so nicht?
Zitat:
TMessageDialog.MessageDlg(Format(conErrorFileNotP resent, ...);" aufteilen. Die Zeile ist sehr lang.
...das ist kein langer String sondern mehrere Parameter.
Zitat:
harte Typecasts vermeiden
...in diesem Falle unnötig. Das was reingeht, kommt wieder raus. Mit der o.g. Version ist auch der Cast Geschichte.