AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Bitmap soll gelegentlich unsichtbar sein
Thema durchsuchen
Ansicht
Themen-Optionen

Bitmap soll gelegentlich unsichtbar sein

Ein Thema von Popov · begonnen am 21. Jan 2014 · letzter Beitrag vom 2. Feb 2014
Antwort Antwort
Seite 4 von 4   « Erste     234   
Benutzerbild von Sir Rufo
Sir Rufo

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

AW: Bitmap soll gelegentlich unsichtbar sein

  Alt 1. Feb 2014, 12:06
Ich weiß ja nicht ob das hier jetzt eine Posse wird ...

... mit dieser (schon mal von mir veröffentlichen Klasse)
Delphi-Quellcode:
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.
und der von dir angegebenen Testroutine
Delphi-Quellcode:
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.
erhalte ich folgendes Ergebnis
dp_178696.png

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 TComponent ).

Am einfachsten erreiche ich das durch das Kopieren der zugewiesenen Instanz (und TBitmap ist num mal auch ein TPersistent und bringt glücklicherweise ein funktionierendes Assign mit).

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.
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
Popov
(Gast)

n/a Beiträge
 
#32

AW: Bitmap soll gelegentlich unsichtbar sein

  Alt 2. Feb 2014, 16:55
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.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 4   « Erste     234   


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 06:39 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