![]() |
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: |
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:
Jetzt der Test
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;
Delphi-Quellcode:
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.
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; |
AW: Bitmap soll gelegentlich unsichtbar sein
Dann müsstest du dir eine eigene Klasse von TGraphic ableiten, die als
![]() |
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...
|
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. |
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:
Und das funktioniert deswegen, weil bei
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; ![]()
Delphi-Quellcode:
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 ;)
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; Darum sollte meine Bitmap-Ableitung genau das erfüllen, was dir da vorschwebt. |
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. |
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; |
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 ![]() 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. |
AW: Bitmap soll gelegentlich unsichtbar sein
Zitat:
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. |
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