![]() |
AW: Bitmap soll gelegentlich unsichtbar sein
sx2008, du solltest den Satz nicht zu wörtlich nehmen. Natürlich wußte ich 100% was ich wollte, nur wenn man nicht weiß was technisch möglich ist, dann weiß man auch nicht wirklich was man - unter der Berücksichtigung des Möglichen - will.
Ich hab bereits im ersten Beitrag geschrieben "Dormant ... Theoretisch genau was ich suche". Einfach Beispiel angucken und schon hättest du erfahren was ich suche. Da gibt es keine Informationen die ich versteckte. Es ist ein Programm mit dem man Objekte in einem Grafikfenster ablegen kann. Jedes Objekt kann mit einem Datensatz in einer einer oder mehreren Tabellen verknüpft werden. Womit die Datensätze visualisiert werden. Objekte können gruppiert werden, womit sie einer oder mehren Gruppen angehören. Womit man so ganz leicht auswerten kann welche Gruppen welche Datensätze enthalten. Man filtert die Ergebnisse somit nicht mit einem Filter, sondern durch Zuordnung von Gruppen. Womit wir bei Ebenen wären. Objekte können nach Bedeutung auf verschiedenen Ebenen abgelegt werden, womit sie zwar einer Gruppe angehören, aber man wiederum steuern kann ob sie bei der Auswertung beachtet werden... Bist du jetzt schlauer? Es ist einfach so (lassen wir die Informationen weg): da gibt es eine Bitmap, je nachdem ob sie dektiviert ist, soll sie gezeichnet oder nicht gezeichnet werden. Da gibt es zwei Möglichkeiten: der Teil des Programm, das die Bitmap zeichnet prüft nach ob er es zeichnen soll, oder, es prüft nichts, sondern zeichnet die Bitmap immer. In dem Fall brauche ich eine Zauberbitmap die im Fall, dass sie nicht gezeichnet werden soll, einfach nichts liefert. Wäre das Möglich, könnte man auf eine Prüfung verzichten. Das war nur eine Idee, eine Bitmap die man abschalten kann. |
AW: Bitmap soll gelegentlich unsichtbar sein
Warum leitest du nicht einfach eine Klasse von TBitmap ab? Überall wo eine TBitamp erstellt werden soll, erstellst du statt dessen eine TZauberbitmap und fertig.
Delphi-Quellcode:
Alternativ könntest du die Eigenschaft "Invisible" auch in der Ebenen-Klasse implementieren.
type
TZauberbitmap = class(TBitmap) procedure Draw(ACanvas : TCanvas; const Rect : TRect); override; private FInvisible: Boolean; public property Invisible: Boolean read FInvisible write FInvisible; end; procedure TZauberbitmap.Draw(ACanvas : TCanvas; const Rect : TRect); begin if Invisible then Exit; inherited; end; TZauberbitmap bekommt ein Property der Klasse Ebene (oder ein Interface) und kann darüber vor dem Zeichnen die Eigenschaft prüfen. Es genügt dann die Eigenschaft bei der Ebene zu setzen und die Anzeige zu aktualisieren. Ich gewinne den Eindruck das in deinem Projekt ein grundsätzliches Problem in der Trennung von Daten, Funktion und Oberfläche liegt. Auch wenn sich einzelne Probleme umgehen lassen, wird das Ganze immer nur noch komplizierter. Deine Versuche das nur an der Oberfläche zu lösen sind vermutlich langfristig zum scheitern verurteilt. |
AW: Bitmap soll gelegentlich unsichtbar sein
|
AW: Bitmap soll gelegentlich unsichtbar sein
Zitat:
Das Problem: ich programmiere nicht das Programm nur Teile davon. Ich bekomme eine TBitmap und gebe eine TBitmap zurück. Wenn ich die Klasse ändern könnte, würde die Frage hier nicht stehen. Was mir verschwebte war die Manipulation der TBitmap. Da das anscheinend nicht möglich ist, hat sich die Frage somit erledigt. //EDIT: Die Lösung #18 ist ok. So in der Art habe ich es auch schon versucht, es ist ja die einfachste Lösung. Die Möglichkeiten über Property habe ich. Der Grund wieso die Lösung noch in der Schwebe ist, ist das kopieren über Assign. Ich finde das übertrieben, will das aber nicht ganz ausschließen. Vielleicht liegt das daran, dass ich da eine gewisse Vorstellung habe. Wenn ich mich von der verabschiedet habe, werde ich evtl. offener sein. |
AW: Bitmap soll gelegentlich unsichtbar sein
Zitat:
Sie behält dabei ihr zauberhaftes Verhalten bei der Ausgabe unsichtbar oder sichtbar zu sein, ansonsten ist es eine ganz normale Bitmap. Ist die Verknüfung mit der Ebene realisiert, kann die Ebene die Sichtbarkeit der Bitmaps in anderen Programmteilen fernsteuern, ohne das diese das besonders berücksichtigen müssten. Ob das im konkreten Fall weiter hilft, kann ich natürlich nicht bewerten. Ich seh grad irgendwie drehn wir uns im Kreis siehe #16, #17. Warum bist du der Meinung deine Rückgabe darf nur eine TBitmap sein und keine abgeleitete Klasse? |
AW: Bitmap soll gelegentlich unsichtbar sein
Sorry für die späte Rückmeldung. Habe eigentlich schon kurz danach geantwortet, sogar einiges, aber anscheinend nicht abgeschickt.
Zum Thema: hier werden immer Tips gegeben, wofür ich dankbar bin, aber, vielleicht habe ich nicht viel drauf, aber einiges kann ich auch programmieren. Und eine Klasse in der ich die Bitmap abschalten kann, habe sogar ich drauf:
Delphi-Quellcode:
Das Problem ist also nicht einen Schalter zu programmieren. Der Code oben funktioniert wunderbar, den habe ich als Übung bereits vor der Fragestellung geschrieben, nur er funktioniert nicht in allen Einzelheiten wie ich es mir vorgestellt habe. Was ich gesucht habe war mir eine evtl. unbekannte Eigenschaft von Bitmap. Ich kenne TBitmap zwar allgemein, aber nicht in Einzelheiten. Was ich bereits paar mal erwähnt habe ist Dormant. Wenn man sich das Beispiel anguckt, dann versteht man was mir eigentlich vorschwebte. Die Bitmap ist da, sie liefert aber nichts. Kaum aber schreibt jemand etwas rein, schon wird sie aktiviert, wird sichtbar und führt die Änderung durch.
type
TTestKlasse = class private FBitmap: TBitmap; FBackup: TBitmap; FVisible: Boolean; protected procedure SetVisible(AVisible: Boolean); public constructor Create; destructor Destroy; override; property Bitmap: TBitmap read FBitmap write FBitmap; property Visible: Boolean read FVisible write SetVisible; end; constructor TTestKlasse.Create; begin FBitmap := TBitmap.Create; FVisible := True; FBackup := nil; end; destructor TTestKlasse.Destroy; begin FBitmap.Free; if FBackup <> nil then FBackup.Free; end; procedure TransparentBitmap(ABitmap: TBitmap); var Brush: TBrush; begin Brush := TBrush.Create; try Brush.Assign(ABitmap.Canvas.Brush); ABitmap.Canvas.Brush.Style := bsSolid; ABitmap.TransparentMode := tmFixed; ABitmap.Canvas.Brush.Color := ABitmap.TransparentColor; ABitmap.Transparent := True; ABitmap.Canvas.FillRect(ABitmap.Canvas.ClipRect); ABitmap.Canvas.Brush.Assign(Brush); finally Brush.Free; end; end; procedure TTestKlasse.SetVisible(AVisible: Boolean); var Brush: TBrush; begin if AVisible = FVisible then Exit; if AVisible then begin FBitmap.Assign(FBackup); FreeAndNil(FBackup); end else begin FBackup := TBitmap.Create; FBackup.Assign(FBitmap); TransparentBitmap(FBitmap); end; FVisible := AVisible; end; procedure TForm1.Button1Click(Sender: TObject); const FilePath = 'C:\Programme\Gemeinsame Dateien\Borland Shared\Images\Splash\256Color\factory.bmp'; var Test: TTestKlasse; begin Test := TTestKlasse.Create; try Test.Bitmap.LoadFromFile(FilePath); Test.Bitmap.Transparent := True; Canvas.Draw(0, Test.Bitmap.Height * 0, Test.Bitmap); Test.Visible := False; Canvas.Draw(0, Test.Bitmap.Height * 1, Test.Bitmap); Test.Visible := True; Canvas.Draw(0, Test.Bitmap.Height * 2, Test.Bitmap); finally Test.Free; end; end; Und das ist der Unterschied zum oberen Code. Wenn einer nicht vorher den Schalter wieder umstellt, zeichnet er ins leere. Zwar könnte man das abfangen und ein SetBitmap schreiben, aber der erste Zugriff würde immer ins Leere gehen. Es besteht also die Gefahr, dass in die falsche Bitmap geschrieben wird. Kommen wir zu Vererbung. Entweder ich verstehe den Hinweis nicht oder man versteht nicht was mir vorschwebt. Allerdings ist die Diskussion inzwischen akademisch, da ich den Code bereits abgeliefert habe. Das bedeutet nicht, dass mich dass allgemein nicht interessiert. Trotzdem, wenn ich eine neue Klasse wollte, hätte ich sie programmiert. Aber wie ich bereits im Eingangspost gesagt habe, es soll TBitmap bleiben. Einigen wir uns vielleicht abschließend darauf, dass mir da etwas vorschwebte, mir allerdings der Wortschatz fehlt mein Problem zu beschreiben. |
AW: Bitmap soll gelegentlich unsichtbar sein
Du hast in Deinem Code ein potentielles Speicherleck und eine potentielle AV. Wenn der Bitmap-Eigenschaft eine andere Bitmap zugewiesen wird, ändert sich der Instanzzeiger von der selbst erstellten auf die zugewiesene, somit kann die selbst erstellte nicht mehr freigegeben werden, stattdessen zieht man beim Zerstören der Klasse womöglich anderen Klassen die Bitmap unter dem Hintern weg. Du kannst das mit einem Setter, innerhalb dessen Du einfach die übergebene Instanz in Deine eigene kopierst (Assign), vermeiden. Somit hast Du dann weiterhin getrennte Instanzen, aber mit gleichen Eigenschaften.
|
AW: Bitmap soll gelegentlich unsichtbar sein
Danke für den Hinweis, aber wie gesagt, es ist nur eine Machbarkeitsstudie gewesen, ein Test, oder wie man das sonst nennt.
Trotzdem, wo siehst du die potentielle Gefahr genau? Ich denke du erkennst die Gefahr dort wo ich sie schon im ersten Post gesehen habe: "Das würde die Aufgabe erfüllen, aber die Objektadresse würde nicht stimmen. Könnte zu Problemen führen wenn einer die nutzen würde." Das ist eigentlich auch der Grund wieso ich es nicht so machen wollte und nach Ideen suchte. Wobei ich das gleiche auch in Blau (nicht in Grün) versucht hatte, also statt einer Backup-Bitmap das Bild in MemoryStream sichern. |
AW: Bitmap soll gelegentlich unsichtbar sein
Die Gefahr besteht einfach darin, dass Du eine Bitmap selbst erzeugst und eine beschreibbare Property ohne Setter deklariert hast. Kleines Beispielprogramm:
Delphi-Quellcode:
type
TTest1 = class private FBitmap: TBitmap; public constructor Create; destructor Destroy; override; (* ohne Setter *) property Bitmap: TBitmap read FBitmap write FBitmap; end; TTest2 = class private FBitmap: TBitmap; procedure SetBitmap(const Value: TBitmap); public constructor Create; destructor Destroy; override; (* mit Setter *) property Bitmap: TBitmap read FBitmap write SetBitmap; end; { TTest1 } constructor TTest1.Create; begin inherited; FBitmap := TBitmap.Create; end; destructor TTest1.Destroy; begin FBitmap.Free; inherited; end; { TTest2 } constructor TTest2.Create; begin inherited; FBitmap := TBitmap.Create; end; destructor TTest2.Destroy; begin FBitmap.Free; inherited; end; procedure TTest2.SetBitmap(const Value: TBitmap); begin (* Eigener Instanz Eigenschaften zuweisen *) FBitmap.Assign(Value); end; procedure TForm1.Button1Click(Sender: TObject); var Test: TTest1; Bitmap: TBitmap; begin Bitmap := TBitmap.Create; try Test := TTest1.Create; try Test.Bitmap := Bitmap; finally Test.Free; end; Bitmap.Width := 100; //<- *Bumm*, wilder Zeiger und Speicherleck finally Bitmap.Free; end; end; procedure TForm1.Button2Click(Sender: TObject); var Test: TTest2; Bitmap: TBitmap; begin Bitmap := TBitmap.Create; try Test := TTest2.Create; try Test.Bitmap := Bitmap; finally Test.Free; end; Bitmap.Width := 100; //alles in Butter, da eigene Instanz finally Bitmap.Free; end; end; |
AW: Bitmap soll gelegentlich unsichtbar sein
Du hast ja Recht. Nur wie gesagt, dieses Problem war mir schon vorher bewusst, auch wenn mein letztes Beispiel ohne Setter und Getter war. Deshalb habe ich auch den Thread erstellt. Das tauschen einer Bitmap ist kein Problem, wie mein letztes Beispiel zeigt. Womit mein Problem eigentlich gelöst wäre. Aber entweder ich arbeite ohne Setter und Getter und riskiere das was du erwähnt hast, oder ich kopiere alles permanent mit Assign. Dann kostet das Zeit. Denn umsonst ist Assign nicht.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:43 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