![]() |
AW: TImages verwalten
Zitat:
Delphi-Quellcode:
Result := TFoo.Create;
try ... except Result.Free; raise; end; |
AW: TImages verwalten
Ich habe das doch so geschrieben, wie das was er machen soll. Und
Delphi-Quellcode:
ist ein Ressourcen-Schutzblock - wenn ich mich da richtig erinnere - und genau den will ich haben und darum schreibe ich ihn so.
try finally
|
AW: TImages verwalten
Zitat:
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:
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.
Result := TFoo.Create;
try ... except Result.Free; // NUR freigeben, wenn es geknallt hat. raise; end;
Delphi-Quellcode:
LFoo := TFoo.Create;
try ... LFoo := nil; ... finally if Assigned(LFoo) then LFoo.Free; end; |
AW: TImages verwalten
Das werde ich definitiv nicht machen, denn ich schreibe keine Kommentare, die sich auf Basis-Funktionalitäten (
Delphi-Quellcode:
prüft selber auf assigned) beziehen, noch füge ich unnützen Code hinzu
TObject.Free
Delphi-Quellcode:
). Ich schreibe keine Tutorials sondern Anwendungen und wer das verstehen möchte, der soll die Sprache beherrschen.
if (Assigned( LFoo ) then LFoo.Free;
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; |
AW: TImages verwalten
Dein
Delphi-Quellcode:
wird immer ausgeführt, macht aber meistens (hoffentlich immer) nichts, was schon einen Kommentar wert wäre. :stupid:
finally LFoo.Free; end;
|
AW: TImages verwalten
Danke für Eure erhellenden Antworten. Natürlich lerne ich gern dazu. Einen "Krieg" anzuzetteln, war das Letzte, was ich mit meiner Fragestellung wollte.
Zitat:
Delphi-Quellcode:
Ich habe jetzt aber konkret das Problem, dass meine (Object)Liste und die tatsächlich in den TabSheets vorhandenen Forms auseinanderfallen können. Denn mir fehlt immer noch das Wissen und auch eine Idee, wie die angedockte Form den Umstand des Schließens und damit das Löschen aus dem Tabsheet an das Hauptprgramm/-form weiterleitet.
Procedure Example;
Var SL : TIrgendwas; Begin SL:=TIrgendwas.Create; Try SL.TuEtwas; Finally SL.Free; End; End; Die Änderung des TabSheets wird mir über
Delphi-Quellcode:
mitgeteilt. Aber wie filtere ich jetzt das verschwundene Fenster aus meiner Liste? Eine Idee wäre natürlich einen Zugriff zu machen, damit dann künstlich eine Exception zu erzeugen und das betreffende Fenster zu löschen; so klappt es jedenfalls. Ich kann mir aber kaum vorstellen, dass das so legitim ist:
TPageControl.OnChange
Delphi-Quellcode:
Daher eben nochmal meine Frage, wie man das macht richtig?
Procedure TMainForm.PCPicsChange(Sender: TObject);
Var I : Integer; lDockForm : TDockForm; Begin I:=0; While (fPicList.Count > I) Do Begin lDockForm:=fPicList.Items[I]; Try lDockForm.RBorgjpg.Checked; Inc(I); // <- hat geklappt, ist also noch vorhanden Except fPicList.Delete(I); End; End; End; Gruß, Alex |
AW: TImages verwalten
Die ganzen DockFormen werden ja im Hauptformular/Programm kreiert.
Da könntest du denen doch eine Callback-Funktion mitgeben, die im OnClose des DockFormulars ausgelöst wird. ![]() |
AW: TImages verwalten
Richtiger wäre es den ganzen Kram zu trennen.
Es gibt eine Liste mit Datenobjekten
Delphi-Quellcode:
Für das DatenObjekt gibt es eine Form, die dieses DatenObjekt anzeigen kann
// ein Datenobjekt
TImageData = class property Filename : string; end;
Delphi-Quellcode:
Die MainForm kann nun aus der Liste mit den DatenObjekten die passenden Forms erzeugen und natürlich auch wieder entfernen.
TImageView = class( TDockForm )
property ImageData : TImageData; end;
Delphi-Quellcode:
Nach jeder Änderung an der
TMainForm = class( TForm )
FDataList : TObjectList; FViewList : TObjectList; procedure PresentDataList; end; procedure TMainForm.PresentDataList; var LView : TImageView; begin for LIdx := 0 to FDataList.Count - 1 do begin if LIdx < FViewList.Count then LView := FViewList[LIdx] as TImageView else begin LView := TImageView.Create( PageControl1 ); FViewList.Add( LView ); LView.ManualDock( PageControl1, nil, alClient ); end; LView.Visible := false; LView.ImageData := FDataList[LIdx] as TImageData; LView.Visible := true; end; // überflüssige Views entfernen for LIdx := FViewList.Count - 1 downto FDataList.Count do begin LView := FViewList[LIdx] as TImageView; FViewList.Delete( LIdx ); LView.Close; end; end;
Delphi-Quellcode:
(Sortieren, Hinzufügen, Entfernen) ruft man einfach
FDataList
Delphi-Quellcode:
auf und der Keks ist gegessen.
PresentDataList
Auf der MainForm ist nun ein Button um das aktuell angezeigte Bild zu entfernen, dann muss man folgendes ausführen
Delphi-Quellcode:
Richter wäre es aber auch hier eine sprechendere Programmierung zu wählen
procedure TMainForm.Button1Click( Sender : TObject );
begin FDataList.Delete( PageControl1.TabIndex ); PresentDataList; end;
Delphi-Quellcode:
Wenn man nämlich aus der ImageView heraus dieses Entfernen auslösen möchte, dann gibt man jeder ImageView einfach dieses als Event mit
procedure TMainForm.Button1Click( Sender : TObject );
begin RemoveCurrentItem; end; procedure TMainForm.RemoveCurrentItem; begin RemoveItem( FDataList[PageControl1.TabIndex] ); end; procedure TMainForm.RemoveItem( AItem : TObject ); begin FDataList.Remove( AItem ); PresentDataList; end;
Delphi-Quellcode:
und in der ImageView wird das dann einfach aufgerufen und alles passiert von selber
procedure TMainForm.PresentDataList;
... LView.OnRemoveItem := RemoveItem; ...
Delphi-Quellcode:
Das möchte ich jetzt aber nicht weiter ausführen, sonst sprengt es den Rahmen.
procedure TImageView.RemoveButtonClick( Sender : TObject );
begin OnRemoveItem( ImageData ); end; Die
Delphi-Quellcode:
Form muss jetzt natürlich im
TImageView
Delphi-Quellcode:
Event die Daten aus dem
OnShow
Delphi-Quellcode:
lesen und entsprechend anzeigen. Hier kann man in dem Setter von ImageData auch noch ein Flag setzen, ob sich ImageData überhaupt geändert hat und kann sich das erneute Einlesen sparen.
ImageData
(da das mit dem Resourcenschutzblock nur zu Verwirrung führt, habe ich mal alles weggelassen, was nicht unbedingt notwendig ist) |
AW: TImages verwalten
Mir ist nicht klar für was du überhaupt ein angedocktes Fenster benötigst.
Ich vermute du vermischt die Anzeige und das Halten der Daten. Wenn zum Bild zusätzliche Einstellungen gehören, dann erweitere einfach die Klasse.
Delphi-Quellcode:
Für die Anzeige genügt eine Paintbox, im OnPaint wird das aktuell ausgewählte Bild mit seinen Einstellungen gezeichnet.
TMyColorStyle = (mycsDefault, mycsGray, mycsBlackAndWhite);
TMyPicture = class(TPicture) private FColorStyle: TMyColorStyle; protected procedure Draw(ACanvas: TCanvas; const Rect: TRect); override; procedure DrawBlackAndWhite((ACanvas: TCanvas; const Rect: TRect); procedure DrawGray(ACanvas: TCanvas; const Rect: TRect); published property ColorStyle: TMyColorStyle read FColorStyle write FColorStyle; end; TMyPictureList = TObjectList<TMyPicture>; procedure TMyPicture.Draw(ACanvas: TCanvas; const Rect: TRect); begin case FColorStyle of mycsGray: DrawGray(ACanvas, Rect); mycsBlackAndWhite: DrawBlackAndWhite(ACanvas, Rect); else inherited Draw(ACanvas, Rect); end; end; Den Steuerelementen werden die zum Bild gehörenden Einstellungen zugewiesen. Vereinfacht:
Delphi-Quellcode:
TMyForm = class(TForm)
procedure DoOnTabChanged(Sender: TObject); procedure DoOnRadioClick(Sender: TObject); procedure DoOnPaintBoxPaint(Sender: TObject); private FPictureList: TMyPictureList; function GetCurrentPicture: TMyPicture; end; procedure TMyForm.DoOnTabChanged(Sender: TObject); var Picture: TMyPicture; ColorStyle: TMyColorStyle; begin Picture := GetCurrentPicture; if Assigned(Picture) then ColorStyle := Picture.ColorStyle else ColorStyle := mycsDefault; RBtnDefault.Checked := ( ColorStyle = mycsDefault ); RBtnGray.Checked := ( ColorStyle = mycsGray ); RBtnBW.Checked := ( ColorStyle = mycsBlackAndWhite ); {neu zeichnen} PaintBox.Invalidate; end; procedure TMyForm.DoOnRadioClick(Sender: TObject); var Picture: TMyPicture; ColorStyle: TMyColorStyle; begin ColorStyle := mycsDefault; Picture := GetCurrentPicture; if Assigned(Picture) then begin if RBtnBW.Checked then ColorStyle := mycsBlackAndWhite else if RBtnGray.Checked then ColorStyle := mycsGray; end; Picture.ColorStyle := ColorStyle; {neu zeichnen} PaintBox.Invalidate; end; procedure TMyForm.DoOnPaintBoxPaint(Sender: TObject); begin PaintBox.Canvas.StretchDraw(PaintBox.ClientRect, GetCurrentPicture); end; function TMyForm.GetCurrentPicture: TMyPicture; var idx: Integer; begin idx := TabControl.TabIndex; if (idx >= 0) and (idx < FPictureList.Count) then Result := FPictureList[idx] else Result := nil; end; |
AW: TImages verwalten
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Ich finde aber die Forms nicht schlecht. Denn ich kann den Code für diese separat verwalten, was den Code später sogar besser warten lässt. Und ich möchte auch keine Querverweise haben. Das heißt, die Fenster wissen nichts voneinander und kümmern sich - bei Bedarf - um das Umwandeln selbst. Es verkompliziert es daher, eine Liste mit den Bilder im Hauptprogramm (=Code des MainForm) vorzuhalten und zu warten - mit Ausnahme der Liste für die Instanzen der Fenster. Ich hatte bereits in meinem ersten Post eingestellt, wie ich es gern hätte. Genau so sieht es jetzt auch aus. Der Zugriff auf die Bild-Daten klappt. Die Bilder sollen auch nicht in Grau angezeigt, sondern nur in Grau gespeichert werden. Ich habe dennoch noch einmal einen Screenshot angehängt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:26 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