Einzelnen Beitrag anzeigen

Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.292 Beiträge
 
Delphi 12 Athens
 
#1

Probleme mit Objektkopie und eigenem MessageDialog

  Alt 19. Dez 2018, 17:45
Hallöle...

Ich stehe wieder mal vor einem Problem das ich nicht verstehe...

Gegeben:
* Klasse:
Delphi-Quellcode:
TDocumentProperties = class(TBaseObject)
  strict private
  {$REGION 'Fields'}
    FStoreLocation: string;
    FStoreStreet: string;
    FReceiptReciverName: string;
    FDocumentTypeString: string;
    FDocumentChoiceString: string;
    FDocumentLocation: TSEAMDocumentLocation;
    FStoreName: string;
    FCreateDate: TDateTime;
    FCreateName: string;
    FCreateYear: Integer;
    FModifiedName: string;
    FModifiedDate: TDateTime;
    FDocumentChoice: TSEAMDocumentChoice;
    FServiceDate: TDateTime;
    FNote: string;
    FStoreCountry: string;
    FReceiptDate: TDateTime;
    FStorePostCode: string;
    FReceiptReciverNumber: string;
    FServicePartnerNumber: string;
    FLocationNumber: string;
    FReceiptNumber: string;
    FStoreName_1: string;
    FDocumentCaption: string;
    FStoreNumber: string;
    FFileName: string;
    FFilePath: string;
    FExtension: string;
    FSendType: string;
    FFileNameContent: TStringList;
    procedure SetExtension(const Value: string);
    procedure SetFileName(const Value: string);
  {$ENDREGION}
  public
    constructor Create;
    destructor Destroy; override;
    property StoreNumber: string read FStoreNumber write FStoreNumber;
    property StoreName: string read FStoreName write FStoreName;
    property StoreName_1: string read FStoreName_1 write FStoreName_1;
    property StoreStreet: string read FStoreStreet write FStoreStreet;
    property StoreCountry: string read FStoreCountry write FStoreCountry;
    property StorePostCode: string read FStorePostCode write FStorePostCode;
    property StoreLocation: string read FStoreLocation write FStoreLocation;
    property Note: string read FNote write FNote;
    property CreateDate: TDateTime read FCreateDate write FCreateDate;
    property CreateName: string read FCreateName write FCreateName;
    property CreateYear: Integer read FCreateYear write FCreateYear;
    property ModifiedDate: TDateTime read FModifiedDate write FModifiedDate;
    property ModifiedName: string read FModifiedName write FModifiedName;
    property ReceiptDate: TDateTime read FReceiptDate write FReceiptDate;
    property ServiceDate: TDateTime read FServiceDate write FServiceDate;
    property DocumentChoice: TSEAMDocumentChoice read FDocumentChoice write FDocumentChoice;
    property DocumentLocation: TSEAMDocumentLocation read FDocumentLocation write FDocumentLocation;
    property DocumentChoiceString: string read FDocumentChoiceString write FDocumentChoiceString;
    property DocumentTypeString: string read FDocumentTypeString write FDocumentTypeString;
    property DocumentCaption: string read FDocumentCaption write FDocumentCaption;
    property SendType: string read FSendType write FSendType;
    property ReceiptNumber: string read FReceiptNumber write FReceiptNumber;
    property ReceiptReceiverNumber: string read FReceiptReciverNumber write FReceiptReciverNumber;
    property ReceiverReceiverName: string read FReceiptReciverName write FReceiptReciverName;
    property ServicePartnerNumber: string read FServicePartnerNumber write FServicePartnerNumber;
    property LocationNumber: string read FLocationNumber write FLocationNumber;
    property Extension: string read FExtension write SetExtension;
    property FileName: string read FFileName write SetFileName;
    property FilePath: string read FFilePath write FFilePath;
    procedure Assign(Source: TObject);
    function EncodeFileName: string;
    procedure DecodeFileName(FileName: string);
  end;
* GUI
Delphi-Quellcode:
procedure TfoDocuments.DoScrollDocuments(FocusedRecord: TcxCustomGridRecord);
var
  MessageList: TStringList;
  FileName: string;

  Test1, Test2: Pointer;
begin
  if FLogic.DocumentDatasource.Changed then
  begin
    MessageList := TStringList.Create;
    try
      FileName := FLogic.ModifiedDocument.FileName;
      MessageList.Add(Format(conTextConfirmationChangedDocument, [QuotedStr(FileName)]));
      MessageList.Add('');
      MessageList.Add(conTextConfirmationChangedDocument_1);
      if TMessageDialog.MessageDlg(MessageList, conTextSaveHeader, vmtQuestion, [buYes, buNo], clBlack, Self) = mrYes then
      begin
        FLogic.SaveDocument;
      end;
    finally
      MessageList.Free;
    end;
  end;

  FLogic.AfterScrollDocuments(FocusedRecord.RecordIndex); // Wechsel des Objekte in der Logic

  Test1 := Pointer(FLogic.OriginalDocument); // Kontrolle
  Test2 := Pointer(FLogic.ModifiedDocument); // Kontrolle

  if FLogic.ModifiedDocument.FileName.EndsWith('.pdf', True) then
  begin
    if FileExists(FLogic.ModifiedDocument.FileName) then
    begin
      WPViewPDF1.LoadFromFile(FLogic.ModifiedDocument.FileName);
    end
    else
    begin
      WPViewPDF1.Clear;
      TMessageDialog.MessageDlg(Format(conErrorFileNotPresent, [QuotedStr(FLogic.ModifiedDocument.FileName)]), conTextCheckHeader, vmtError, [buOk], clBlack, Self); // --> Zugriffsverletzung aus dem TReader im OnCreate der Dialog Form (siehe Unit)
    end;
  end;

  ShowDocument(FLogic.ModifiedDocument);
end;
* Logic
Delphi-Quellcode:
constructor TFormDocumentsLogic.Create(Preferences: TSEAMPreferences);
begin
  inherited Create(Preferences);
  FDocumentDatasource := TSEAMDocumentsDatasource.Create;
  FDocumentDatasource.OnChange := DoOnChange;
  FOriginalDocument := nil; // aus Liste
  FModifiedDocument := nil; // über Objektkopie
  FLastStoreName := '';
end;
...
procedure TFormDocumentsLogic.AfterScrollDocuments(FocusedRecordIndex: Integer);
begin
  FOriginalDocument := FDocumentDatasource.GetObject(FocusedRecordIndex); // Pointer aus Liste bleibt unangetastet
  if Assigned(FModifiedDocument) then // mit jedem Scroll die "Kopie" austauschen
  begin
    FModifiedDocument.Free;
  end;
  FModifiedDocument := TSEAMDocumentProperties(TSEAMToolsJson.ObjectCopy(FOriginalDocument)); // Kopie des Originals aus der Liste
  //wenn ich diese Zeile auskommentiere wird der Dialog angezeigt.
end;
* Objektkopie (funktioniert eigentlich immer)
Delphi-Quellcode:
class function TToolsJson.ObjectCopy(aValue: TObject): TObject;
var
  MarshalObj: TJSONMarshal;
  UnMarshalObj: TJSONUnMarshal;
  JSONValue: TJSONValue;
begin
  Result := nil;
  MarshalObj := TJSONMarshal.Create;
  try
    UnMarshalObj := TJSONUnMarshal.Create;
    try
      JSONValue := MarshalObj.Marshal(aValue);
      try
        if Assigned(JSONValue) then
          Result := UnMarshalObj.Unmarshal(JSONValue);
      finally
        JSONValue.Free;
      end;
    finally
      UnMarshalObj.Free;
    end;
  finally
    MarshalObj.Free;
  end;
end;

Problem:

1. Wenn ich ausschließlich das Originalobjekt oder ein leeres Objekt benutze (ohne FModifiedDocument Kopie), dann wird der Dialog angezeigt.
Delphi-Quellcode:
FModifiedDocument := TDocumentProperties.Create; //(TToolsJson.ObjectCopy(FOriginalDocument));
.
2. Wenn ich das Originalobjekt kopiere, auch bei der Benutzung von FOriginalDocument, kommt eine Zugriffsverletzung im OnCreate der Dialog Form.


Frage:

Was hat der Reader der Form damit zu tun? Der Code des MessageDialogs ist in Ordnung...


Danke...
Miniaturansicht angehängter Grafiken
fehler.png   break.jpg   dialog.png  

Geändert von haentschman (20. Dez 2018 um 06:24 Uhr)
  Mit Zitat antworten Zitat