Delphi-PRAXiS
Seite 2 von 4     12 34      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Bitmap soll gelegentlich unsichtbar sein (https://www.delphipraxis.net/178696-bitmap-soll-gelegentlich-unsichtbar-sein.html)

HHennig 22. Jan 2014 09:48

AW: Bitmap soll gelegentlich unsichtbar sein
 
Schau dir mal die GR32-Library an und im Besonderen TImage32 und ggf. dessen Nachfahren, dort gibt es Layering und es ist m. E. sehr gut gelöst.
Klar ist die ganze Library von Grund auf anders aufgebaut als TBitmap und Konsorten, aber vielleicht kannst du ja einige Denkanstöße entnehmen. In den mitgelieferten Examples gibt es auch ein Beispiel zu den Layern, ebenso ist das Prinzip in der CHM-DFatei ausführlich erläutert.
Ein wenig Spitzeln wie andere das machen ist ja erlaubt :wink:

Popov 22. Jan 2014 16:22

AW: Bitmap soll gelegentlich unsichtbar sein
 
Ok, vielleicht klingt mein erstes Post etwas verwirrend, vermutlich aber nur, weil ich mir einige Szenarien schon im Kopf durchgespielt habe und weiß, dass sie nicht funktionieren. Während es im ersten Moment für den Leser durchaus noch als machbar klingt. Natürlich stellt sich dann die Frage wo das Problem ist?

Ich hab gerade mein Gedankenspiel in Code umgesetzt um es zu prüfen. Hier das Problem mit einer leeren Ersatz-Bitmap.

Zuerst eine Beispielklasse:
Delphi-Quellcode:
type
  TKlasseB = class
  private
    FBitmap: TBitmap;
    FEmptyBitmap: TBitmap;
    FBitmapEnabled: Boolean;
  protected
    function GetBitmap: TBitmap;
  public
    constructor Create;
    destructor Destroy; override;
    property Bitmap: TBitmap read GetBitmap write FBitmap;
    property BitmapEnabled: Boolean read FBitmapEnabled write FBitmapEnabled;
  end;

constructor TKlasseB.Create;
begin
  FBitmap := TBitmap.Create;
  FBitmapEnabled := True;
  FEmptyBitmap := TBitmap.Create;
end;

destructor TKlasseB.Destroy;
begin
  FBitmap.Free;
  FEmptyBitmap.Free;
end;

function TKlasseB.GetBitmap: TBitmap;
begin
  if FBitmapEnabled then
    Result := FBitmap
  else
  begin
    Result := FEmptyBitmap;
    Result.Assign(FBitmap);
    Result.Canvas.Brush.Style := bsSolid;
    Result.Canvas.Brush.Color := Result.TransparentColor;
    Result.Transparent := True;
  end;
end;
Jetzt der Test
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Bmp: TBitmap;
begin
  with TKlasseB.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;
Das Problem tritt nicht auf wenn man direkt mit der Bitmap der Klasse arbeitet. Vielleicht ist das Korinthenkacker, aber die Klasse ist in meinen Augen nicht wasserdicht. Man würde in dem Fall mit zwei verschiedenen Bitmaps arbeiten können.

Namenloser 22. Jan 2014 17:52

AW: Bitmap soll gelegentlich unsichtbar sein
 
Dann müsstest du dir eine eigene Klasse von TGraphic ableiten, die als Proxy für ein TBitmap dient.

jaenicke 23. Jan 2014 11:01

AW: Bitmap soll gelegentlich unsichtbar sein
 
Viel sinnvoller ist doch aber nur eine TBitmap zu nutzen pro Layer und den Layer selbst seinen Layer zeichnen zu lassen wie ich schon vorgeschlagen hatte. Dann ist das ganze sauber gekapselt, man kann die Layeroperationen auch gleich mit kapseln und das Problem mit mehreren Bitmaps gibt es auch nicht...

Popov 23. Jan 2014 14:33

AW: Bitmap soll gelegentlich unsichtbar sein
 
Du hast Recht, und im Grunde bin ich mit dem Punkt auch nicht glücklich. Nur ist für mich eine Klasse auch immer ein abgeschlossenes Gebilde, somit sollte eine zweite Klasse nicht etwas deuten was die erste versäumt hat.

Das Problem kommt davon, weil ich etwas, was im Grunde in eine Klasse gehört, aus Bequemlichkeit auf zwei Klassen verteilt habe. Und nun habe ich ein Kommunikationsproblem.

Ich denke ich lasse es so wie es bisher ist - in der einen Klasse ist ein Flag ohne weiter Eigenschaften. Die zweite Klasse richtet sich dann nach dem Flag ob sie den Layer beachten soll.

Das Ganze wird sonst zu fehleranfällig.

Sir Rufo 23. Jan 2014 15:04

AW: Bitmap soll gelegentlich unsichtbar sein
 
Versuch es mal hiermit.

Ich habe jetzt nur das Zeichnen verhindert, aber das könnte genauso gut auch umgeleitet werden auf ein leeres Bitmap mit der gleichen Größe ;)
Delphi-Quellcode:
  TLayerBitmap = class( TBitmap )
  private
    FCanDraw : Boolean;
  protected
    procedure Draw( ACanvas : TCanvas; const Rect : TRect ); override;
    procedure DrawTransparent(ACanvas: TCanvas; const Rect: TRect; Opacity: Byte); override;
  public
    property CanDraw : Boolean read FCanDraw write FCanDraw;
  end;

{ TLayerBitmap }

procedure TLayerBitmap.Draw( ACanvas : TCanvas; const Rect : TRect );
begin
  if not FCanDraw then
    Exit;
  inherited;
end;

procedure TLayerBitmap.DrawTransparent(ACanvas: TCanvas; const Rect: TRect; Opacity: Byte);
begin
  if not FCanDraw then
    Exit;
  inherited;
end;
Und das funktioniert deswegen, weil bei Delphi-Referenz durchsuchenTCanvas.Draw irgendwann einmal das hier aufgerufen wird
Delphi-Quellcode:
procedure TCanvas.Draw(X, Y: Integer; Graphic: TGraphic);
begin
  if (Graphic <> nil) and not Graphic.Empty then
  begin
    ...
    Graphic.Draw(Self, Rect(X, Y, X + Graphic.Width, Y + Graphic.Height));
    ...
  end;
end;
Und wenn man das sieht, dann weiß man auch, dass die Umleitung auf ein leeres Bitmap den gleichen Effekt hat, als wenn man das Zeichnen abbricht ;)

Darum sollte meine Bitmap-Ableitung genau das erfüllen, was dir da vorschwebt.

Popov 26. Jan 2014 12:06

AW: Bitmap soll gelegentlich unsichtbar sein
 
@SR

Der letzte Tipp ist für sich genommen ok, gute Idee, das Problem liegt aber im Detail. Vielleicht kann man das Problem lösen (bzw. vermutlich, denn im Grunde kann man alles lösen), aber die Bitmap muss eine TBitmap sein (also keine abgeleitete). Das liegt daran, dass andere Teile des Programms, bzw. andere Klassen eine TBitmap erwarten. Ich müßte also alles andere anpassen, und dafür ist das Programm inzwischen zu groß geworden.

Ich lasse vorerst die alte Lösung. Sie ist nicht schön, aber funktioniert.

Sir Rufo 26. Jan 2014 15:35

AW: Bitmap soll gelegentlich unsichtbar sein
 
Wieso, die Klasse erfüllt genau das, was du gefordert hast, auch in dem von dir beschriebenen Kontext
Delphi-Quellcode:
type
  TKlasseB = class
  private
    FBitmap: TLayerBitmap;
  protected
    function GetBitmap: TBitmap;
    procedure SetBitmap( const Value : TBitmap );
    function GetBitmapEnabled : Boolean;
    procedure SetBitmapEnabled( const Value : Boolean );
  public
    constructor Create;
    destructor Destroy; override;
    property Bitmap: TBitmap read GetBitmap write SetBitmap;
    property BitmapEnabled: Boolean read GetBitmapEnabled write SetBitmapEnabled;
  end;

constructor TKlasseB.Create;
begin
  inherited;
  FBitmap := TLayerBitmap.Create;
end;

destructor TKlasseB.Destroy;
begin
  FBitmap.Free;
  inherited;
end;

function TKlasseB.GetBitmap: TBitmap;
begin
  Result := FBitmap;
end;

procedure TKlasseB.SetBitmap( const Value : TBitmap );
begin
  FBitmap.Assign( Value );
end;

function TKlasseB.GetBitmapEnabled : Boolean;
begin
  Result := FBitmap.CanDraw;
end;

procedure TKlasseB.SetBitmapEnabled( const Value : Boolean );
begin
  FBitmap.CanDraw := Value;
end;

Popov 28. Jan 2014 22:28

AW: Bitmap soll gelegentlich unsichtbar sein
 
Jetzt nicht falsch verstehen, ich hab hier paar Ideen erfahren an die ich selbst nicht gedacht habe. Ich werde an dem Thema weiter arbeiten, aber aktuell drängt ein Termin und auch wenn auch die aktuelle Lösung mir persönlich nicht gefällt, sie funktioniert.

Ich weiß im Grunde auch nicht so richtig was ich wollte. Ich hab da das Beispiel unter Delphi-Referenz durchsuchenDormant gesehen und das brachte mich auf die Idee statt eine Bitmap nicht zu zeichnen, dafür keine Bitmap zu liefern.

Was ich nicht will ist Bitmaps hin und her kopieren. Das würde klappen, aber das wäre mit Kanonen auf Spatzen schießen. Irgendwie schwebte mir da ein leeres Nichts. Aber das mit Canvas ist schon eine gute Idee. Ich werde das mal testen. Vielleicht ist auch Dormant die Lösung, nur blicke ich nicht nicht 100% durch was im Hintergrund da passiert.

sx2008 29. Jan 2014 00:16

AW: Bitmap soll gelegentlich unsichtbar sein
 
Zitat:

Zitat von Popov (Beitrag 1245765)
Ich weiß im Grunde auch nicht so richtig was ich wollte.

Das hab ich schon gewußt als ich meinen ersten Betrag in diesem Thema geschrieben habe.
In meinem zweiten Betrag war ich auch nicht von einer Party zurück sondern nur genervt von deiner Art sämliche wichtige Informationen zurückzuhalten.
Wenn du einerseits nicht bereit bist eigene Ideen, die nicht funktionieren, zurückzustellen und andererseits nicht willens bist das ganze Problemumfeld zu beschreiben dann wirst du nie eine gute Lösung finden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:08 Uhr.
Seite 2 von 4     12 34      

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