Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   TPaintbox löscht Zeichenfläche selbstständig (GDI+) (https://www.delphipraxis.net/191832-tpaintbox-loescht-zeichenflaeche-selbststaendig-gdi.html)

SiLo0815 23. Feb 2017 23:06


TPaintbox löscht Zeichenfläche selbstständig (GDI+)
 
Guten Abend zusammen!

Ich möchte mehrere Bilder als Thumbnails auf meine Programmoberfläche zeichnen. Dazu habe ich eine Scrollbox erstellt, welche ein Flowpanel beinhaltet.
Zu diesem Flowpanel füge ich zur Laufzeit TPaintBox-Objekte hinzu und zeichne mit der GDI+-Bibliothek (http://www.bilsen.com/gdiplus/index.shtml) die Thumbnails auf deren Zeichenflächen.

Meine Thumbnail-Klasse speichert zusätzlich den Dateinamen und sieht so aus:
Delphi-Quellcode:
type
  TThumbnail = class(TPaintBox)
    private
      FFilename: String;
    public
      property Filename: String read FFilename write FFilename;
  end;
Die Thumbnails werden (per Schleife über eine Liste von Dateinamen (f)) so erzeugt:
Delphi-Quellcode:
Image := TGPImage.Create(f);
Thumbnail := Image.GetThumbnailImage(150, 150, nil, nil);

OutputImage := TThumbnail.Create(Self);
OutputImage.AlignWithMargins := true;
OutputImage.Height := 150;
OutputImage.Width := 150;
OutputImage.Filename := f;
OutputImage.Cursor := crHandPoint;
OutputImage.OnClick := ThumbnailClick;
OutputImage.Parent := flwpnlImageView;

Graphics := TGPGraphics.Create(OutputImage.Canvas.Handle);
Graphics.DrawImage(Thumbnail, 0, 0, Thumbnail.Width, Thumbnail.Height);
Nun ist das Problem, dass mir die Bilder zwar kurz angezeigt werden, kurz darauf aber wieder verschwinden.
Ich habe die Vermutung, dass sich die Paintboxen bedingt durch die Scrollbox neu zeichnen und dann wieder leer sind.
Interessanterweise funktioniert das ganze, wenn ich TThumbnail von TImage ableite. Ich würde der Geschwindigkeit wegen aber lieber TPaintbox benutzen.
Hat vielleicht jemand eine Idee, was ich versuchen könnte, um die Bilder dauerhaft zu sehen?

Grüße
Simon

Edit2: Sorry für den halbfertigen Post zu Beginn, ich hab' versucht den Code mit TAB einzurücken und hab Enter gedrückt - zack, schon war's abgeschickt... :oops:

Luckie 23. Feb 2017 23:30

AW: TPaintbox löscht Zeichenfläche selbstständig (GDI+)
 
Zeichne auf ein Bitmap im Speicher unf kopiere dies im OnPaint Ereignis auf den Canvas der Psintbox.

SiLo0815 23. Feb 2017 23:36

AW: TPaintbox löscht Zeichenfläche selbstständig (GDI+)
 
Danke für den Tipp, Luckie!
Also liege ich mit meiner Vermutung richtig, dass das (leere) OnPaint-Ereignis der Paintbox aufgerufen und die Zeichenfläche dadurch wieder geleert wird?
Warum funktioniert das ganze dann beim TImage? Schützt TImage seine Zeichenfläche irgendwie vor einem Repaint?
Bitmaps in den Speicher zu legen wäre eine Alternative, ich mache mir nur Gedanken wegen des Speicherverbrauchs.

SiLo0815 24. Feb 2017 00:01

AW: TPaintbox löscht Zeichenfläche selbstständig (GDI+)
 
Ich habe den Tipp mit dem Bitmap mal umgesetzt:

Delphi-Quellcode:
type
  TThumbnail = class(TPaintbox)
    private
      FFilename: String;
      FPicture: TBitmap;
    protected
      procedure Paint; override;
    public
      property Filename: String read FFilename write FFilename;
      property Picture: TBitmap read FPicture write FPicture;
  end;

procedure TThumbnail.Paint;
begin
  inherited;
  if Assigned(Picture) then begin
    Self.Canvas.Draw(0, 0, Picture);
  end;
end;
Erzeugung:
Delphi-Quellcode:
Image := TGPImage.Create(f);
Thumbnail := Image.GetThumbnailImage(150, 150, nil, nil);
Bitmap := TBitmap.Create;
Bitmap.Height := 150;
Bitmap.Width := 150;
Graphics := TGPGraphics.Create(Bitmap.Canvas.Handle);
Graphics.DrawImage(Thumbnail, 0, 0, Thumbnail.Width, Thumbnail.Height);

OutputImage := TThumbnail.Create(Self);
OutputImage.AlignWithMargins := true;
OutputImage.Height := 150;
OutputImage.Width := 150;
OutputImage.Filename := f;
OutputImage.Cursor := crHandPoint;
OutputImage.OnClick := ThumbnailClick;
OutputImage.Picture := Bitmap;
OutputImage.Parent := flwpnlImageView;
Soweit ich sehen kann, funktioniert es! Ist das jetzt die beste Lösung?

jaenicke 24. Feb 2017 03:37

AW: TPaintbox löscht Zeichenfläche selbstständig (GDI+)
 
Das ist die einzige korrekte Lösung. Eine TPaintBox hat keinen eigenen Zwischenspeicher. Kommt also vom Betriebssystem ein WM_PAINT, sprich die Aufforderung das Control neu zu zeichnen, kann die PaintBox alleine dem nicht nachkommen und reicht das daher an das OnPaint weiter.

Rollo62 24. Feb 2017 10:24

AW: TPaintbox löscht Zeichenfläche selbstständig (GDI+)
 
Die Paintbox ist wohl zum "selberzeichnen" gedacht.
So wie oben würde ich es auch machen, aber du könntest z.B. auch Linien, Rechtecke oder sonstige Objekte auf den Canvas zeichnen.
Du musst dann aber Alles immer im OnPaint neuzeichnen.

Ist die Frage was im Einzelfall weniger Ressourcen/Performance braucht.
In deinem Fall sind die ShadowBitmaps schon OK würde ich sagen.

Rollo

SiLo0815 24. Feb 2017 18:51

AW: TPaintbox löscht Zeichenfläche selbstständig (GDI+)
 
Vielen Dank für eure Anmerkungen, ich lasse es jetzt so. :)

Luckie 24. Feb 2017 19:25

AW: TPaintbox löscht Zeichenfläche selbstständig (GDI+)
 
Vergess aber nicht die Ressourcen wieder freizugeben, wenn du sie nicht mehr brauchst, sonst läuft dir der Speicher voll.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:32 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