Eigene Klasse mit eigener Fehlerbehandlung ausstatten
So, jetzt wird es etwas komplizierter. In diesem Topic: OOP FileSplitter ging es darum einen FileSplitter schön in einer Klasse zu packen. Zur Übung habe ich mich mal dran gesetzt und habe da eine Klasse entworfen. Ging wunder bar, mit Event und allem.
So jetzt wollte ich die Klasse TFileSplitter mit einem eigenem Exception Handling, oder wie man es auch immer nennen will ausstatten. Dabei bin ich auf ein paar Probleme gestossen. Erst mal die EFileSplitterError Klasse:
Delphi-Quellcode:
type
TOnError = procedure(Sender: TObject; ECode: Integer; EMessage: string) of object; EFileSplitterError = class(Exception) private FOnError: TOnError; public property OnError: TOnError read FOnError write FOnError; end; Jetzt die Einbindung in die TFileSplitter Klasse:
Delphi-Quellcode:
Idee: Ist kein Eventhandler zu gewiesen, soll eine ganz normale Exception geworfen werden. Das klappt aber nicht. Assigned(OnError) liefert immer True wie es aussieht.
type
TOnProgress = procedure(Sender: TObject; PartFilename: string; Total, Done: Int64) of object; TFileSplitter = class private FSError: EFileSplitterError; ...; public ...; procedure Execute; public ...; property OnError: EFileSplitterError read FSError write FSError; end; [..] procedure TFileSplitter.Execute; var ...; resourcestring EEmptyFile = 'Keine Datei angegeben.'; ...; begin if FFilename = '' then begin if Assigned(OnError) then begin FSError.OnError(self, 1, EEmptyFile); exit; end else raise Exception.Create(EEmptyFile); end; [..] end; Und im Programm:
Delphi-Quellcode:
Er sagt mir immer bei der Zuweisung des Events:
type
TForm1 = class(TForm) ...; private { Private-Deklarationen } ...; procedure SplitError(Sender: TObject; ECode: Integer; EMessage: String); public { Public-Deklarationen } end; [..] procedure TForm1.SplitError; var s: String; begin s := 'Fehlercode: '+IntToStr(ECode)+#13#10; s := s + EMessage; Messagebox(Handle, PChar(s), 'Fehler', MB_ICONSTOP); end; procedure TForm1.Button1Click(Sender: TObject); var fs: TFileSplitter; begin fs := TFileSplitter.Create; try ...; fs.OnError := SplitError; fs.Execute; finally FreeAndNil(fs); end; end; Zitat:
|
Re: Eigene Klasse mit eigener Fehlerbehandlung ausstatten
Hallo Luckie,
die Parameter von SplitError fehlen in der Implementierung.
Delphi-Quellcode:
procedure TForm1.SplitError(Sender: TObject; ECode: Integer; EMessage: String);
var s: String; begin s := 'Fehlercode: '+IntToStr(ECode)+#13#10; s := s + EMessage; Messagebox(Handle, PChar(s), 'Fehler', MB_ICONSTOP); end; |
Re: Eigene Klasse mit eigener Fehlerbehandlung ausstatten
Das war es nicht. Gleicher Fehler. Hätte mich auch gewundert, da ich den Event für den Fortschritt genauso konstruiert habe und da geht es.
Delphi-Quellcode:
Und im Programm:
type
TOnProgress = procedure(Sender: TObject; PartFilename: string; Total, Done: Int64) of object; TFileSplitter = class private ...; FOnProgress: TOnProgress; ...; public constructor Create; procedure Execute; public ...; property OnProgress: TOnProgress read FOnProgress write FOnProgress; end; [..] repeat BytesRead := inFile.Read(Buffer, Min(sizeof(Buffer), BytesToRead)); BytesWritten := outFile.Write(Buffer, BytesRead); Dec(BytesToRead, sizeof(Buffer)); if Assigned(OnProgress) then begin OnProgress(self, PartFilename, inFile.Size, inFile.Position); end; until BytesToRead < 0;
Delphi-Quellcode:
type
TForm1 = class(TForm) ...; private { Private-Deklarationen } procedure SplitProgress(Sender: TObject; PartFilename: String; Total, Done: Int64); public { Public-Deklarationen } end; [..] procedure TForm1.SplitProgress; begin ProgressBar1.Max := 100; ProgressBar1.Position := Done * 100 div Total; Label1.Caption := PartFilename; Application.ProcessMessages; end; [..] procedure TForm1.Button1Click(Sender: TObject); var fs: TFileSplitter; begin fs := TFileSplitter.Create; try fs.Filename := edtFile.Text; fs.DestFolder := edtDestFolder.Text; fs.PartSize := StrToInt(edtPartFileSize.Text) * 1024; fs.OnError := SplitError; fs.OnProgress := SplitProgress; fs.Execute; finally FreeAndNil(fs); end; end; |
Re: Eigene Klasse mit eigener Fehlerbehandlung ausstatten
Problem 1 hat sich gerade irgendwie von selbst gelöst. Muss noch mal kucken, was ich geändert habe. Das Problem mit den fehlenden Parametern beim Zuweisen des Eventhandlers besteht weiterhin.
|
Re: Eigene Klasse mit eigener Fehlerbehandlung ausstatten
Liste der Anhänge anzeigen (Anzahl: 1)
Hat da niemand eine Idee? Ich hänge das Projekt mal an, dann wird es eventuell einfachher für euch.
|
Re: Eigene Klasse mit eigener Fehlerbehandlung ausstatten
Delphi-Quellcode:
kann ja nicht funktionieren, weil OnError ja vom Typ EFileSplitterError ist und SplitError ne Prozedur. Eigentlich müsste es ja dann heissen:
fs.OnError := SplitError;
Delphi-Quellcode:
Was auch zuweisungstechnisch geht, aber fs.OnError (die Exception) ist ja in dem Fall noch nicht initialisiert.
fs.OnError.OnError := SplitError;
Ich würde den Error so deklarieren:
Delphi-Quellcode:
Der Aufruf wäre dann so:
EFileSplitterError = class(Exception)
protected FErrorCode : Integer; public constructor CreateError(const AErrCode: Integer; const AMessage: string); reintroduce; virtual; property ErrorCode: Integer read FErrorCode; end; //... constructor EFileSplitterError.CreateError(const AErrCode: Integer; const AMessage: string); begin inherited Create(AMessage); FErrorCode := AErrCode; end;
Delphi-Quellcode:
TFileSplitter = class
private FSError: TOnError; //... property OnError: TOnError read FSError write FSError; end; //... if Assigned(OnError) then begin OnError(self, 1, EEmptyFile); exit; end else raise EFileSplitterError.CreateError(1, EEmptyFile); |
Re: Eigene Klasse mit eigener Fehlerbehandlung ausstatten
Hm, so weit, so gut.
Jetzt haut das auslösen des Events aber nicht hin:
Delphi-Quellcode:
if Assigned(OnError) then
begin OnError(self, 1, EEmptyFile); // Zeile 148 exit; end Zitat:
|
Re: Eigene Klasse mit eigener Fehlerbehandlung ausstatten
Liste der Anhänge anzeigen (Anzahl: 1)
Deswegen hab ich ja auch oben die Deklaradion von OnError geändert.
Schau dir mal die geänderte Klasse anbei an. |
Re: Eigene Klasse mit eigener Fehlerbehandlung ausstatten
Zitat:
Danke, so geht es bestens. :thumb: Mal sehen, ob ich das noch irgendwie dokumentiere und der Allgemeinheit zur Verfügung stellen kann. :wink: |
Re: Eigene Klasse mit eigener Fehlerbehandlung ausstatten
Eins noch: Wie muss der EFileSplitter Constructur aussehen, damit ich ein Parameter Array übergeben kann wie der normalen CraeteFm Methode von der Klasse Exception?
Habs:
Delphi-Quellcode:
type
TOnError = procedure(Sender: TObject; ECode: Integer; EMessage: string) of object; EFileSplitterError = class(Exception) protected FErrorCode : Integer; public constructor CreateError(const AErrCode: Integer; const AMessage: string; const Arg: array of const); reintroduce; virtual; property ErrorCode: Integer read FErrorCode; end;
Delphi-Quellcode:
constructor EFileSplitterError.CreateError(const AErrCode: Integer;
const AMessage: string; const Arg: array of const); begin inherited CreateFmt(AMessage, Arg); FErrorCode := AErrCode; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz