![]() |
Try Except End; verschachteln
Hallo,
ich weiß nicht genau, ob meine Frage hierher gehört. Sollte das nicht so sein, dann bitte ich den/die Zuständigen, das mal entsprechend zu verschieben. In meinem Programm werden Grafikverarbeitungen gemacht, die auf Teufel komm raus zu Ende geführt werden müssen. Zudem möchte ich mich nicht darauf verlassen, dass die angelieferten Listen mit den Grafik-Dateien die passenden Endungen zu den Formaten haben. Standard ist bei mir png, dann jpeg, ggf. auch bmp und ansonsten eine Fehlermeldung. Im Moment mache ich das so (Bitte beachten: Das ist nur eine Ausschnitt. Im Programm gibt es kein OpenDialog1, sondern eine TStringList mit zig Dateien):
Delphi-Quellcode:
Kann man das irgendwie kürzer, schöner, eleganter, besser machen?
Procedure Machwas;
Var tPNG : TPngObject; tJPG : TJPEGImage; tBMP : TBitmap; Begin If (Not OpenDialog1.Execute) Then Exit; tPNG:=TPngObject.Create; tJPG:=TJPEGImage.Create; tBMP:=TBitmap.Create; Try Try tPNG.LoadFromFile(OpenDialog1.FileName); Image1.Picture.Assign(tPNG); Except Try tJPG.LoadFromFile(OpenDialog1.FileName); Image1.Picture.Assign(tJPG); Except Try tBMP.LoadFromFile(OpenDialog1.FileName); Image1.Picture.Assign(tBMP); Except ShowMessage('Unbekanntes Dateiformat:' + #13 + OpenDialog1.FileName); End; End; End; Finally tPNG.Free; tJPG.Free; tBMP.Free; End; End; Mein Problem ist, dass dieser Code mehrfach im Programm auftaucht und diese Schachtelei mit der Zeit nicht besonders schön ist und die Lesbarkeit und damit die spätere Wartung des Codes sehr eingeschränkt sind. Gruß und danke fürs drüberschauen, Alex |
AW: Try Except End; verschachteln
Hallo,
ich würde hergehen und das Bildformat ermitteln. Nicht anhand der Dateiendung, sondern am Header. Wobei die Prüfung der Dateiendung oft auch gehen würde. Den Dateityp bekommst du über den Header ![]() Dann kannst du evtl. um alles herum noch ein einziges try - except basteln. |
AW: Try Except End; verschachteln
Wie sieht das aus?
Delphi-Quellcode:
Die Erkennung überlasse ich Delphi, das ja dank registrierbarer Formate flexibel ist (z.B. GrapicEx)
function LoadGraphic(Filename : string; Bitmap : TBitmap): Boolean;
var Picture : TPicture; begin Result := true; Picture := TPicture.Create; try try Picture.LoadFromFile(filename); except on EInvalidGraphic do Result := false; end; try Bitmap.Assign(Picture.Graphic) except on EConvertError do Result := false; end; finally Picture.Free; end; end; €: Bin mir aber beim TS nicht sicher, ob überhaupt erwünscht ist, alle Rastergrafik-Formate als einheitliches TBitmap zu erhalten. €2: Vor Bitmap.Assign könnte man noch Result checken... muss aber nicht... Bitmap.Assign(nil) ist meiner Erfahrung nach kein Problem. |
AW: Try Except End; verschachteln
Meine Variante:
Delphi-Quellcode:
Der Code ist ungetestet und soll nur zur Veranschaulichung dienen. Ich bin zudem grad nicht sicher, ob das mit der Konstantendeklaration so klappt -- ich kann mir nie merken, mit welchen Typen der Compiler das mitmacht und mit welchen nicht. Eventuell muss man die Konstante in eine Variable ändern und dann manuell befüllen.
//type
// Grad nicht sicher, ob es nen enstprechenden Typ schon gibt: // TGraphicClass = class of TGraphic; function CreateImageFromFile(const Filename: string): TGraphic; var Adapter: TGraphicClass; const ADAPTERS: array[0..2] of TGraphicClass = (TPNGObject, TJPEGImage, TBitmap); begin Result := nil; for Adapter in ADAPTERS do begin if Assigned(Result) then break; Result := Adapter.Create; try Result.LoadFromFile(Filename); except FreeAndNil(Result); end; end; if not Assigned(Result) then raise EInvalidGraphic.CreateFmt('Unknown format: "%s"', [Filename]); end; var Graphic: TGraphic; begin if (OpenDialog1.Execute) then begin try Graphic := CreateImageFromFile(OpenDialog1.FileName); try Image1.Picture.Graphic.Assign(Graphic); finally Graphic.Free; end; except on E: EInvalidGraphic do MessageBox(0, PChar(E.Message), 'Konnte Datei nicht laden', MB_OK or MB_ICONERROR); else raise E; end; end; end; Vorteil meiner Lösung: Lässt sich leicht erweitern. @Satty67: TPicture unterscheidet aber afair nur nach Dateiendungen und das reicht dem OP nicht. |
AW: Try Except End; verschachteln
Zitat:
|
AW: Try Except End; verschachteln
@NamenLozer:
Dein (ungetesteter) Code passt wie die Faust aufs Auge! Er läuft bei mir perfekt. Richtig ist insoweit auch, dass mich das Format nicht wirklich interessiert. Somit spare ich die Zeit und Performance, vorher erst den Header auslesen zu müssen. Da standard bei meiner Software PNG, dann JPG und erst zum Schluss BMP ist, kann man super die Reihenfolge des durch Exception geschützten Ladens bestimmen... Ich komme echt ins Schwärmen! Herzlichen Dank, Alex |
AW: Try Except End; verschachteln
die Try-Except-Verschachtelungen wurden ja nurn schon geklärt, aber nun noch was zur Verschachtelung von Try-Finally, bzw. des Resourcen-Schutzblocks:
Zitat:
Also eigentlich sollte es so aussehn, damit alles korrekt freigegeben würde:
Delphi-Quellcode:
Eventuell geht auch Folgendes.
tPNG := TPngObject.Create;
Try tJPG := TJPEGImage.Create; Try tBMP := TBitmap.Create; Try ... Finally tBMP.Free; End; Finally tJPG.Free; End; Finally tPNG.Free; End; Dieses geht aber nur, wenn man davon ausgehn kann, daß es beim Freigeben (hier in .Free) keine Probleme auftreten können. (OK, Fehler, welche sowieso den nachfolgenden Programmfluß irreversibel schädigen, kann man gern ignorieren, da dann sowieso alles Egal ist :stupid: )
Delphi-Quellcode:
bzw. "verkürzt":
tPNG := nil;
tJPG := nil; tBMP := nil; Try tPNG := TPngObject.Create; tJPG := TJPEGImage.Create; tBMP := TBitmap.Create; ... Finally tPNG.Free; tJPG.Free; tBMP.Free; End;
Delphi-Quellcode:
tJPG := nil;
tBMP := nil; tPNG := TPngObject.Create; Try tJPG := TJPEGImage.Create; tBMP := TBitmap.Create; ... Finally tPNG.Free; tJPG.Free; tBMP.Free; End; |
AW: Try Except End; verschachteln
Tritt im Konstruktor eine Exception auf, wird der schon belegte Speicher und das Objekt automatisch wieder freigegeben. Oder ich mache seit 15 Jahren was falsch, wenn ich schreibe:
Delphi-Quellcode:
obj := TObject.Create
try ...; ...; finally obj.Free: end; |
AW: Try Except End; verschachteln
IMHO nein
ich hatte himitsu auch nicht anders verstanden Zitat:
|
AW: Try Except End; verschachteln
Zitat:
Bei einem Objekt, stimmt diese Annahme. Tritt hier aber z.B. in TJPEGImage.Create eine Exception auf, so wird dieses Objekt von Delphi freigeben, aber das vorher erstellte tPNG wird dabei nicht mit freigegben ... wie auch. > tPNG/TPngObject wird erstellt und bleibt erhalten > tJPG/TJPEGImage wird zwar erstellt, aber durch die Exception automatisch freigegeben > tBMP/TBitmap wird erst garnicht erstellt, da die Verarbeitung hier noch nicht vorbeikam > der Finally-Block und alle .Free werden nicht aufgerufen, da dieses ebenfalls nicht mehr ausgeführt werden |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:38 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz