![]() |
AW: Bitmap soll gelegentlich unsichtbar sein
Liste der Anhänge anzeigen (Anzahl: 1)
Ich weiß ja nicht ob das hier jetzt eine Posse wird ...
... mit dieser (schon mal von mir veröffentlichen Klasse)
Delphi-Quellcode:
und der von dir angegebenen Testroutine
unit DrawLayer;
interface uses Windows, Graphics; type TEnableBitmap = class( TBitmap ) private FEnabled : Boolean; protected procedure Draw( ACanvas : TCanvas; const Rect : TRect ); override; procedure DrawTransparent( ACanvas : TCanvas; const Rect : TRect; Opacity : Byte ); override; public procedure AfterConstruction; override; property Enabled : Boolean read FEnabled write FEnabled; end; TDrawLayer = class private FBitmap : TBitmap; procedure SetBitmap( const Value : TBitmap ); function GetBitmapEnabled : Boolean; procedure SetBitmapEnabled( const Value : Boolean ); public procedure AfterConstruction; override; property Bitmap : TBitmap read FBitmap write SetBitmap; property BitmapEnabled : Boolean read GetBitmapEnabled write SetBitmapEnabled; end; implementation { TEnableBitmap } procedure TEnableBitmap.AfterConstruction; begin inherited; FEnabled := True; end; procedure TEnableBitmap.Draw( ACanvas : TCanvas; const Rect : TRect ); begin if FEnabled then inherited; end; procedure TEnableBitmap.DrawTransparent( ACanvas : TCanvas; const Rect : TRect; Opacity : Byte ); begin if FEnabled then inherited; end; { TDrawLayer } procedure TDrawLayer.AfterConstruction; begin inherited; FBitmap := TEnableBitmap.Create; end; function TDrawLayer.GetBitmapEnabled : Boolean; begin Result := ( FBitmap as TEnableBitmap ).Enabled; end; procedure TDrawLayer.SetBitmap( const Value : TBitmap ); begin FBitmap.Assign( Value ); end; procedure TDrawLayer.SetBitmapEnabled( const Value : Boolean ); begin ( FBitmap as TEnableBitmap ).Enabled := Value; end; end.
Delphi-Quellcode:
erhalte ich folgendes Ergebnis
unit FormMain;
interface uses DrawLayer, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TMainForm = class( TForm ) Panel1 : TPanel; Button1 : TButton; procedure Button1Click( Sender : TObject ); end; var MainForm : TMainForm; implementation {$R *.dfm} { TMainForm } procedure TMainForm.Button1Click( Sender : TObject ); var Bmp : TBitmap; begin with TDrawLayer.Create do try Bitmap.Canvas.Brush.Color := clRed; Bitmap.Width := 100; Bitmap.Height := 50; Self.Canvas.Draw( 0, 0, Bitmap ); // Bis jetzt alles ok // Jetzt das Problem BitmapEnabled := False; // Man denkt sich nichts böses dabei, ist ja auch erlaubt Bmp := Bitmap; Bmp.Canvas.Ellipse( Bmp.Canvas.ClipRect ); Self.Canvas.Draw( 100, 100, Bmp ); // Nun stimmt nichts nicht überein. Wo ist die Ellipse? BitmapEnabled := True; Self.Canvas.Draw( 200, 200, Bitmap ); finally Free end; end; end. Anhang 40647 Es macht genau das was du gefordert und beschrieben hast. Warum du auf dem Assign rumreitest, kann ich nicht nachvollziehen. Wenn eine Eigenschaft mit Schreibzugriff eine Klasse ist, dann muss gewährleistet sein, dass dort kein Speicherleck auftritt. Und es gilt auch die allgemeine Regel, wer die Instanz erzeugt ist auch für das Aufräumen zuständig. Andernfalls muss diese Aufgabe klar delegiert werden (z.B. Owner bei
Delphi-Quellcode:
).
TComponent
Am einfachsten erreiche ich das durch das Kopieren der zugewiesenen Instanz (und
Delphi-Quellcode:
ist num mal auch ein
TBitmap
Delphi-Quellcode:
und bringt glücklicherweise ein funktionierendes
TPersistent
Delphi-Quellcode:
mit).
Assign
Und wie dir auffällt wird in deiner gesamten Testprozedur das Assign nicht einmal aufgerufen (weil ja direkt mit der Bitmap-instanz gearbeitet wird). Also könnte die Eigenschaft Bitmap auch ReadOnly sein. Dann entfällt der Setter und damit das Assign (wenn es denn die/deine Augen stören sollte). Bitte erläutere uns doch jetzt, was noch fehlt, denn dein Test wird zu 100% korrekt abgearbeitet. |
AW: Bitmap soll gelegentlich unsichtbar sein
Ich reite nicht auf Assign rum, auch habe ich nichts dagegen, nur gingen die Antworten von Anfang an in eine andere Richtung als die Frage ursprünglich gemeint war. Ich sehe den Fehler bei mir, ich denke ich habe die Frage missverständlich gestellt. Ich gehe jetzt aber auch nicht erneut drauf ein.
Bei dem Programm geht es um visuelle Darstellung von Informationen. Sowas gibt es schon, deshalb gibt es Erfahrungswerte. Hauptsächlich werden Polygone, Linien usw. gezeichnet, aber auch Bitmaps. Eigentlich sind die Bitmaps nur ein Extra, nicht das Eigentliche, aber falls sie eingefügt werden, wird es bei paar hundert Bitmaps eng und das Refresh kann dann Sekunden dauern. Somit ist alles was unnötig Zeit kostet nicht optimal, z. B. Assign. Wenn ich also nun (im Fall der Fälle) mit paar hundert Bitmaps zu tun habe, dann stellt sich mir die Frage ob ich für jedes Refresh auch paar hundert Mal Bitmaps mit Assign hin und her kopieren möchte. Oder gibt es da eine bessere Möglichkeit? Nun habe ich gerade 1 Million Assigns über eine 800*640 Pixel große Bitmap in einer Schleife ausgeführt. Entweder hat der Compiler erkannt, dass das Unsinn war und hat alles optimiert, oder Assign kostet kaum Zeit. Zumindest hat mein Test unter 100 Millisekunden gedauert. Erscheint mir wenig. Vielleicht hatte ich einfach nur eine falsche Vorstellung von Assign und das Kopieren kostet wirklich kaum Zeit. In dem Fall ist es eine Option. Was mein letztes Beispiel angeht, das sehe ich nicht als Fehler. Ich hab da bewusst auf Getter und Setter verzichtet, weil es in dem Beispiel nur um den Switch ging. Es war nur ein Test. Ein Getter und Setter war somit nicht nötig. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:41 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