AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Try Except End; verschachteln

Ein Thema von Schwedenbitter · begonnen am 5. Nov 2010 · letzter Beitrag vom 7. Nov 2010
Antwort Antwort
Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#1

Try Except End; verschachteln

  Alt 5. Nov 2010, 21:47
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:
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;
Kann man das irgendwie kürzer, schöner, eleganter, besser machen?

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
Alex Winzer
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#2

AW: Try Except End; verschachteln

  Alt 5. Nov 2010, 22:03
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 so.

Dann kannst du evtl. um alles herum noch ein einziges try - except basteln.
  Mit Zitat antworten Zitat
Satty67

Registriert seit: 24. Feb 2007
Ort: Baden
1.566 Beiträge
 
Delphi 2007 Professional
 
#3

AW: Try Except End; verschachteln

  Alt 5. Nov 2010, 22:18
Wie sieht das aus?

Delphi-Quellcode:
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;
Die Erkennung überlasse ich Delphi, das ja dank registrierbarer Formate flexibel ist (z.B. GrapicEx)

€: 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.

Geändert von Satty67 ( 5. Nov 2010 um 22:33 Uhr)
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#4

AW: Try Except End; verschachteln

  Alt 5. Nov 2010, 22:43
Meine Variante:
Delphi-Quellcode:
//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;
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.

Vorteil meiner Lösung: Lässt sich leicht erweitern.

@Satty67: TPicture unterscheidet aber afair nur nach Dateiendungen und das reicht dem OP nicht.

Geändert von Namenloser ( 5. Nov 2010 um 22:45 Uhr)
  Mit Zitat antworten Zitat
Satty67

Registriert seit: 24. Feb 2007
Ort: Baden
1.566 Beiträge
 
Delphi 2007 Professional
 
#5

AW: Try Except End; verschachteln

  Alt 5. Nov 2010, 23:03
TPicture unterscheidet aber afair nur nach Dateiendungen und das reicht dem OP nicht.
Stimmt, hatte ich nicht beachtet.
  Mit Zitat antworten Zitat
Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#6

AW: Try Except End; verschachteln

  Alt 5. Nov 2010, 23:28
@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
Alex Winzer
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.163 Beiträge
 
Delphi 12 Athens
 
#7

AW: Try Except End; verschachteln

  Alt 7. Nov 2010, 21:16
die Try-Except-Verschachtelungen wurden ja nurn schon geklärt, aber nun noch was zur Verschachtelung von Try-Finally, bzw. des Resourcen-Schutzblocks:
Zitat:
Delphi-Quellcode:
tPNG := TPngObject.Create;
tJPG := TJPEGImage.Create; // 1
tBMP := TBitmap.Create;
Try
  ...
Finally
  tPNG.Free;
  tJPG.Free;
  tBMP.Free;
End;
1: Hier eine Exception (z.B. OutOfMemory und Co.) und schon wird tPNG nicht freigegeben.

Also eigentlich sollte es so aussehn, damit alles korrekt freigegeben würde:
Delphi-Quellcode:
tPNG := TPngObject.Create;
Try
  tJPG := TJPEGImage.Create;
  Try
    tBMP := TBitmap.Create;
    Try
      ...
    Finally
      tBMP.Free;
    End;
  Finally
    tJPG.Free;
  End;
Finally
  tPNG.Free;
End;
Eventuell geht auch Folgendes.
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 )
Delphi-Quellcode:
tPNG := nil;
tJPG := nil;
tBMP := nil;
Try
  tPNG := TPngObject.Create;
  tJPG := TJPEGImage.Create;
  tBMP := TBitmap.Create;
  ...
Finally
  tPNG.Free;
  tJPG.Free;
  tBMP.Free;
End;
bzw. "verkürzt":
Delphi-Quellcode:
tJPG := nil;
tBMP := nil;
tPNG := TPngObject.Create;
Try
  tJPG := TJPEGImage.Create;
  tBMP := TBitmap.Create;
  ...
Finally
  tPNG.Free;
  tJPG.Free;
  tBMP.Free;
End;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#8

AW: Try Except End; verschachteln

  Alt 7. Nov 2010, 22:43
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;
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#9

AW: Try Except End; verschachteln

  Alt 7. Nov 2010, 23:06
IMHO nein
ich hatte himitsu auch nicht anders verstanden
Zitat:
Also eigentlich sollte es so aussehn, damit alles korrekt freigegeben würde:
der verkürzte Teil könnte IMHO bei tBMP.Free knallen.
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.163 Beiträge
 
Delphi 12 Athens
 
#10

AW: Try Except End; verschachteln

  Alt 7. Nov 2010, 23:50
Zitat:
Delphi-Quellcode:
tPNG := TPngObject.Create;
tJPG := TJPEGImage.Create; // hier Exception im Constructor
tBMP := TBitmap.Create;
Try
  ...
Finally
  tPNG.Free;
  tJPG.Free;
  tBMP.Free;
End;
Nein Luckie, du täuchst dich nicht.
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
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:57 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