AGB  ·  Datenschutz  ·  Impressum  







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

TImages verwalten

Ein Thema von Schwedenbitter · begonnen am 10. Okt 2014 · letzter Beitrag vom 5. Nov 2014
Antwort Antwort
Schwedenbitter

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

AW: TImages verwalten

  Alt 14. Okt 2014, 17:16
Danke für die Erläuterungen.
... Das ist eine Methode, die ich geschrieben habe ... die allerdings besser die Form-Instanz zurückliefert
Delphi-Quellcode:
procedure TMyForm.DockNewForm( APageControl : TPageControl; ADockFormClass : TDockFormClass ) : TDockForm;
var
  LForm : TDockForm;
begin
  LForm := TDockFormClass.Create( APageControl );
  try
    LForm.ManualDock( APgeControl, nil, alClient );
    LForm.Visible := True;
    Result := LForm;
    LForm := nil;
  finally
    LForm.Free;
  end;
end;
OK.
Aber müsste es nicht richtiger Weise dann function statt procedure heißen?
Und wo genau wird die Instanz übergeben (Result:=... oder Var in der Definition der Procedure)?

Was interessiert es dich, was in dem TImage drin ist? Das wird für die Anzeige benötigt ... aus und Ende.
Es interessiert mich deshalb, weil ich damit gern arbeiten würde. Es soll 4 Möglichkeiten geben, die Bilder zu speichern. Über den Button soll das Bild gelöscht werden können. Und damit schließe ich (und geben den Speicher frei) dann zunächst erst einmal bloß die Form. Ich will/muss also nicht nur an die Bilddaten, sondern auch herausbekommen, welches der RadioButtons gewählt wurde. Und das sollte theoretisch über das Code-Beispiel funktionieren, wenn ich Deine Antwort richtig interpretiere. Ich verstehe bloß nicht wie.

Erstelle dir ein Daten-Objekt, was alle Informationen beinhaltet und merke dir dort alle Informationen zu jedem gescannten Bild und organisiere diese in einer Liste. Zu jedem Daten-Objekt gibt es dann eine Form (der du das zugehörige Daten-Objekt an die Hand gibts), die die Inhalte aus dem Daten-Objekt anzeigen und auch die Eingaben des Benutzers dort ablegen kann.

Wenn der Benutzer fertig ist, dann gehts du einfach durch deine Liste und arbeitest die einzelnen Bilder ab. Die einzelnen Forms interessieren nicht mehr
Genau das war/ist ja meine (Ausgangs)Frage. Wie organisiere ich diese Liste? Leite ich sie von TStringList ab? Oder einfach bloß von TList?... Mit TImageList arbeite ich im Moment schon. Aber das ist mir zu unkomfortabel.
Alex Winzer
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: TImages verwalten

  Alt 14. Okt 2014, 17:20
Zitat:
Aber müsste es nicht richtiger Weise dann function statt procedure heißen?
Ja.
Zitat:
Und wo genau wird die Instanz übergeben (Result:=... oder Var in der Definition der Procedure)?
Als Result nur im gezeigten Code wird diese vorher freigegeben ( im finally), was imho keinen Sinn macht.
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: TImages verwalten

  Alt 14. Okt 2014, 18:40
Als Result nur im gezeigten Code wird diese vorher freigegeben ( im finally), was imho keinen Sinn macht.
Die Form-Instanz wird eben nicht freigegeben, ausser es kommt innerhalb der Methode zu einer Exception, dann wird abgebrochen, demzufolge nichts zurückgegeben und darum durch das finally die Instanz freigegeben.

Das ist eigentlich eine sehr übliche und sinnvolle Vorgehensweise wenn man nicht auf Speicherlecks steht.
Delphi-Quellcode:
function FooFactory : TFoo;
var
  LFoo : TFoo;
begin
  LFoo := TFoo.Create;
  try
    ...
    Result := Lfoo;
    LFoo := nil; // auf nil setzen
  finally
    // bei einer Exception wird die Instanz freigegeben,
    // sonst nicht, denn dann zeigt LFoo ja auf nil ;o)
    LFoo.Free;
  end;
end;
Auch wenn es sich im Beispiel um eine Komponente mit Owner handelt, was für eine korrekte Freigabe durch den Owner sorgt. Eine ungenutzte Instanz im Speicher ist zuviel und solche Fehler (Speicher läuft im Betrieb voll) sind nachher nur schwer zu finden, denn beim Beenden gibt es kein Speicherleck, dafür ist irgendwann der Speicher voll und die Anwendung verabschiedet sich.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Schwedenbitter

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

AW: TImages verwalten

  Alt 14. Okt 2014, 19:20
Danke. Es wird langsam klarer und zeigt sich, dass es für Gelegenheitprogrammierer wie mich schwer werden dürfte. Ich habe jetzt folgendes zusammengebastelt. Allerdings weiß ich nicht, wie ich herausbekomme, ob der Benutzer ein Form selbst mit Close "zerstört" hat:
Delphi-Quellcode:
Type
   TMainForm   = Class(TForm)
                     BtnAdd   : TButton;
                     BtnInfo   : TButton;
                     PCPics   : TPageControl;
                     Procedure FormCreate(Sender: TObject);
                     Procedure BtnAddClick(Sender: TObject);
                     Procedure BtnInfoClick(Sender: TObject);
                     Procedure FormDestroy(Sender: TObject);
                 Protected
                     fCount   : Integer;
                     fPicList   : TList;
                 End;

Var
   MainForm      : TMainForm;

Implementation

{$R *.dfm}

Procedure TMainForm.FormCreate(Sender: TObject);
Begin
   fCount:=0;
   fPicList:=TList.Create;
End;

Procedure TMainForm.BtnAddClick(Sender: TObject);
Var
   aPNG         : TPngImage;
   lForm         : TDockForm;
Begin
   aPNG:=TPngImage.Create;
   Try
      aPNG.LoadFromFile('.TestBilder\_0001.png');
      aPNG.RemoveTransparency;
      lForm:=TDockFormClass.Create(PCPics);
      Try
         lForm.ManualDock(PCPics, nil, alClient);
         lForm.Visible:=True;
         LForm.IMGScan.Picture.Bitmap.Assign(aPNG);
         Inc(fCount);
         lForm.Caption:='Bild ' + FormatFloat('0,', fCount);
         fPicList.Add(lForm);   // <- in Liste merken
         lForm:=nil;            // 1:1 übernommen
      Finally
         lForm.Free;            // 1:1 übernommen
         PCPics.ActivePageIndex:=Pred(PCPics.PageCount);
      End;
   Finally
      aPNG.Free;
   End;
End;

Procedure TMainForm.BtnInfoClick(Sender: TObject);
Var
   I            : Integer;
   lDockForm         : TDockForm;
Begin
   If (fPicList.Count = 0) Then Exit;
   I:=PCPics.ActivePageIndex;
   lDockForm:=fPicList.Items[I];// <- so greife ich jetzt zu.
   With lDockForm Do
   Try
      ShowMessage('Original' + #09 + BoolToStr(RBorgjpg.Checked, True));
   Finally
   End;
End;

Procedure TMainForm.FormDestroy(Sender: TObject);
Begin
   Try
      While (fPicList.Count > 0) Do fPicList.Delete(0);
   Finally
      fPicList.Free;
   End;
End;

End.
[edit]
Also der Zugriff klappt.
Bleibt die Frage, wie ich herausbekomme, ob der Benutzer eine Form gelöscht hat...
[/edit]
Alex Winzer

Geändert von Schwedenbitter (14. Okt 2014 um 19:44 Uhr) Grund: Mögliche Teillösung gefunden.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

AW: TImages verwalten

  Alt 14. Okt 2014, 20:54
Die Form-Instanz wird eben nicht freigegeben, ausser es kommt innerhalb der Methode zu einer Exception, dann wird abgebrochen,
Delphi-Quellcode:
LFoo := TFoo.Create;
try
  ...
  Result := Lfoo;
  LFoo := nil; // auf nil setzen
finally
  // bei einer Exception wird die Instanz freigegeben,
  // sonst nicht, denn dann zeigt LFoo ja auf nil ;o)
  LFoo.Free;
end;
Warum schreibt man den Code dann nicht so, wie das, was er machen soll und sparrt dabei auch gleich noch die leicht verwirrende doppelte Variable?
Delphi-Quellcode:
Result := TFoo.Create;
try
  ...
except
  Result.Free;
  raise;
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 Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: TImages verwalten

  Alt 14. Okt 2014, 21:53
Ich habe das doch so geschrieben, wie das was er machen soll. Und try finally ist ein Ressourcen-Schutzblock - wenn ich mich da richtig erinnere - und genau den will ich haben und darum schreibe ich ihn so.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

AW: TImages verwalten

  Alt 15. Okt 2014, 09:14
das was er machen soll.
Also bei einem Fehler eine Aktion ausführen?

OK, es funktioniert Beides, aber IMHO ist es mit'm Finally etwas schneller missverständlicher.

Delphi-Quellcode:
LFoo := TFoo.Create;
try
  ...
  LFoo := nil; // Womöglich auch noch tief in irgendwelchen IFs versteckt auf nil setzen.
  ...
finally
  LFoo.Free; // IMMER freigeben, außer irgendwo anders wurde vorher die Variable heimlich auf nil gesetzt.
end;
Delphi-Quellcode:
Result := TFoo.Create;
try
  ...
except
  Result.Free; // NUR freigeben, wenn es geknallt hat.
  raise;
end;
Ich weiß, im Falle von Free muß nicht geprüft werden, da es das selber macht, aber irgenwie sollte man hier schon, beim Free, einen Hinweis geben ... sei es in Form eines Codes oder als Kommentar, daß sich oben irgendwo noch ein :=nil versteckt.
Delphi-Quellcode:
LFoo := TFoo.Create;
try
  ...
  LFoo := nil;
  ...
finally
  if Assigned(LFoo) then
    LFoo.Free;
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (15. Okt 2014 um 09:20 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: TImages verwalten

  Alt 15. Okt 2014, 10:33
Das werde ich definitiv nicht machen, denn ich schreibe keine Kommentare, die sich auf Basis-Funktionalitäten (TObject.Free prüft selber auf assigned) beziehen, noch füge ich unnützen Code hinzu if (Assigned( LFoo ) then LFoo.Free; ). Ich schreibe keine Tutorials sondern Anwendungen und wer das verstehen möchte, der soll die Sprache beherrschen.

Wie man Instanzen aufräumt sollte eigentlich bekannt sein und gehört zum Basiswissen:
Delphi-Quellcode:
procedure Example;
var
  LFoo : TFoo;
  LBar : TBar;
begin
  LFoo := nil;
  LBar := nil;
  try
    LFoo := TFoo.Create;

    while LFoo.NeedsMore do
    begin
      LBar := TBar.Create;
      LFoo.InteractWith( LBar );
      FreeAndNil( LBar );
    end;

  finally
    LFoo.Free;
    LBar.Free;
  end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  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 20:02 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