Autor |
Beitrag |
Martello
      
Beiträge: 131
WIN 2000
TP, C, Delphi 1.0, Turbo Delphi 2006, Delphi 7
|
Verfasst: Fr 27.03.09 13:40
Hallo,
bei meinem Programm wird der Inhalt der dargestellten Paintbox (Kurvendiagrmm) gelöscht, wenn ein Windowsfenster darüber aufgeht (SAVE-Dialog). Kann man den Inhalt einer solchen Paintbox buffern, und somit einfach neu zeichen lassen?
Mo.
|
|
Xentar
      
Beiträge: 2077
Erhaltene Danke: 2
Win XP
Delphi 5 Ent., Delphi 2007 Prof
|
Verfasst: Fr 27.03.09 13:41
Eine Paintbox zeichnet sich doch automatisch neu..? Du musst natürlich das richtige Event, glaub TPaintBox.OnPaint nehmen, und nicht "von außen".
_________________ PROGRAMMER: A device for converting coffee into software.
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 27.03.09 13:41
www.michael-puff.de/...ffScreenBitmap.shtml
// EDIT:
Richtig, eine TPaintBox benutzt man ja eigentlich auch nur indem man in OnPaint den Inhalt zeichnet, der dauerhaft drin sein soll.
|
|
Martello 
      
Beiträge: 131
WIN 2000
TP, C, Delphi 1.0, Turbo Delphi 2006, Delphi 7
|
Verfasst: Fr 27.03.09 16:35
jaenicke hat folgendes geschrieben : |
// EDIT:
Richtig, eine TPaintBox benutzt man ja eigentlich auch nur indem man in OnPaint den Inhalt zeichnet, der dauerhaft drin sein soll. |
Ich habe die Kurvenschar am Programmanfang durch Auslesen von Werten aus einer Text-Datei gezeichnet.
Das widerspricht sicherlich gutem oop-Stil. War aber bequem, weil der alte Code nur um eine Zeile (for i..; lineto i,Wert) an entsprechender Stelle erweitert werden mußte.
Der Malbefehl erfolgte also nicht durch Mausklick oder anderes auf die PaintBox, somit ganz ohne Steuerereignis (z.B. OnPaint), sondern ergab sich aus dem Programmablauf des alten TP-Codes an bestimmter Stelle. Könnte man hier ansetzen und durch eine Erweiterung das Objekt PaintBox "komplettieren"?
Mo.
|
|
JayEff
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Fr 27.03.09 17:02
male das ganze statt auf die Paintbox in eine globale variable vom typ Bitmap und nutze im onPaint der Paintbox Paintbox.Canvas.Draw(1, 1, myBitmap); dann sollte das Bild immer wenn nötig neu gezeichnet werden. Alle Zeichenoperationen müssen dann nur auf die Bitmap durchgeführt werden. Weiß nicht, wie das Performance-Technisch aussieht aber sollte ok sein 
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 27.03.09 17:12
Um ein Flackern zu vermeiden zeichne ich oft auch auf die Hintergrundbitmap und die PaintBox. So erreiche ich, dass die Änderungen sowohl sofort sichtbar sind (ohne die komplette Box neu zeichnen zu lassen), aber auch bei einem neu zeichnen des Fensters sichtbar bleiben.
|
|
Martello 
      
Beiträge: 131
WIN 2000
TP, C, Delphi 1.0, Turbo Delphi 2006, Delphi 7
|
Verfasst: Fr 27.03.09 17:25
JayEff hat folgendes geschrieben : | male das ganze statt auf die Paintbox in eine globale variable vom typ Bitmap und nutze im onPaint der Paintbox Paintbox.Canvas.Draw(1, 1, myBitmap); dann sollte das Bild immer wenn nötig neu gezeichnet werden. Alle Zeichenoperationen müssen dann nur auf die Bitmap durchgeführt werden. Weiß nicht, wie das Performance-Technisch aussieht aber sollte ok sein  |
Als "Variablen" kenne bisher nur die Typen, die TP ohne Graphik:-) zur Verfügung stellt.
Wie kann ich denn eine Bitmap-Variable vereinbaren bzw. erzeugen? Wie definiere ich das Aussehen, die Größe etc.?
Mo.
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 27.03.09 17:31
Wie wäre es, wenn du dir den Link oben einmal anschaust... Da ist der komplette Quelltext eines Beispiels zu sehen... 
|
|
JayEff
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Fr 27.03.09 17:38
Martello hat folgendes geschrieben : | Wie kann ich denn eine Bitmap-Variable vereinbaren bzw. erzeugen? Wie definiere ich das Aussehen, die Größe etc.? |
Schau dir den Link an, wie jaenicke gesagt hat, aber um auch in diesem Thread die Frage kurz zu beantworten: Der Typ ist TBitmap, das Objekt muss per b := TBitmap.Create; initialisiert werden. Schau dir die Eigenschaften des Typs an (Width, Height, etc  ) dann kannst du sicherlich deren Bedeutung erkennen (Width ist zum Beispiel nicht die Menge der schwarzen Pixel sondern etwas naheliegenderes  ).
Alles andere, was wichtig für den Umgang mit dem Objekt ist, findest du in jaenickes link 
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
Martello 
      
Beiträge: 131
WIN 2000
TP, C, Delphi 1.0, Turbo Delphi 2006, Delphi 7
|
Verfasst: Fr 27.03.09 17:40
|
|
Martello 
      
Beiträge: 131
WIN 2000
TP, C, Delphi 1.0, Turbo Delphi 2006, Delphi 7
|
Verfasst: Fr 27.03.09 17:43
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 27.03.09 18:02
In der Hinsicht ist es ja egal welche Delphiversion du nutzt. Einen Unterschied macht es ja nur bei visuellen Komponenten und anderen, die du auf das Formular legen kannst.
Das ist bei TBitmap ja nicht der Fall. Es ist so oder so nur eine Klasse, die erzeugt werden muss. Entweder nimmt dir das irgendwo eine andere Klasse ab oder du musst es selbst machen. Und im Fall einer solchen unsichtbaren Hintergrundbitmap bleibt dir gar nichts anderes übrig.
Wenn du dich um das Neuzeichnen nicht selbst kümmern willst, dann kannst du höchstens TImage benutzen. Das behält seinen Inhalt auch wenn es neu gezeichnet wird, weil ein anderes Fenster drüber war. Du musst dafür aber den alten Inhalt des Bildes ggf. manuell mit einem Rechteck z.B. übermalen. Denn sonst wird eine neue Linie nur über das alte Bild drübergemalt.
|
|
JayEff
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Fr 27.03.09 18:10
Martello hat folgendes geschrieben : | Genau diese "Creationen" hat bisher jedes Mal (in meinem kurzen Delphileben) der allmächtige Automat im Hintergrund für mich durchgeführt.  |
Hier ein etwas tieferes Verständnis dazu: Die Variable vom Typ TBitmap (Und allgemein von allen Klassen) ist nur ein Zeiger auf einen Speicherbereich, in dem die Datenstruktur steht. Das heißt, effektiv steht in der Variable eine Speicheradresse. Am Anfang wird diese Adresse nil sein, Not In List (hieß das iirc), ein Zeiger ins Nichts. (Man sollte sich bei Zeigern nicht darauf verlassen, dass diese automatisch mit nil initialisiert werden.) Das bedeutet auch, dass kein Speicher für das Objekt vorhanden ist. Der Konstruktor der TBitmap, aufgerufen durch TBitmap.Create; reserviert nun diesen Speicher und gibt die Adresse zurück, an der sich das Objekt befindet. Man sagt, du weißt der Variable eine Instanz der Klasse TBitmap zu.
Achtung! Delphi-Quelltext 1: 2: 3: 4:
| var a, b: TBitmap; begin
a := b; | Hier weißt du der Variable a die Adresse der Variable b zu, du kopierst nicht den Inhalt der Bitmap, wie das z.B. bei Integer der Fall gewesen wäre. Das bedeutet Konkret, hast du für die Variable a schon Speicher reserviert (a := TBitmap.Create; aufgerufen), so hast du hier ein so genanntes Speicherleck, denn die Adresse, die in a gespeichert war, geht verloren obwohl das Objekt noch da ist. Ausserdem, wenn du jetzt b.Free; aufrufst, wird der Speicher von b freigegeben und aber a zeigt immernoch darauf! Das ist ganz schön gefährlich
Last but not least: Objekte die du erstellst müssen immer mit a.Free; freigegeben werden (Es gibt wenige Ausnahmen; Nicht .Destroy aufrufen - das macht .Free für dich  ), dadurch verhinderst du ebenfalls Speicherlecks (wenn du nicht den Fehler von oben machst  ). Am besten sorgst du mit try finally end; dafür, dass auch im Fall einer Exception während der Ausführung von {*Code*} die Freigabe durchgeführt wird.
Das ist jetzt alles hier ein halb OffTopic Klassen-/Pointer-/Instanzenbriefing gewesen aber naja, ich denke schaden wird's nicht, das mal zu wissen 
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
|