Du muß dir mal das Prinzip von Windows vor die Augen halten, dann hast du die Lösung auch schon vor dir.
Also *holttiefluft*. Windows funktioniert über Nachrichten, das heißt jedes eintretende Ereignis löst einen Nachriht aus, auf die dein Programm reagiert. Seies, dass du mit Code Windows bzw deinem Programm explizit sagst was passieren soll oder das Windows die standard Behandlungsroutine ausführt. Bei einem Klick auf einem Button wäre das BM_CLICK. Beim Erzeugen eines fensters wäre das WM_CREATE.
Was passiert nun, wenn dein Fenster von einem anderen überlagert wird und es dann weggenommen wird? Nun der Bereich des Desktop wird für ungültig erklärt. Windows weiß nun nicht, was es darstellen soll. Das alleine weiß nur das wieder sichtbar gewordenen Fenster bzw. Programm. Also schickt Windows an das betreffende Fenster eine Nachricht, die es dazu veranlaßt sich neu zu zeichnen (WM_PAINT).
Bei den standard Kontrolls (Buttons, Listboxen etc.) braucht es dazu keinen Code von dir. Windows weiß wie sie aussehen und dein Programm kann WM_PAINT an die Fensterprozedur dieser Kontrolls weiterleiten. Diese bearbeitet nun WM_PAINT welche die Kontrolls neu zeichnet.
Bei der Paintbox geht das nicht. Wie auch Windows, bzw. die standard fensterprozedur weiß ja nicht, was du da drauf gezeichnet hast. Also wird diser Bereich deines Fenster bzw. der Paintbox weiß von Windows dargestellt.
So die Lösung ist nun recht einfach. Die Paintbox speziell besitzt das Ereignis OnPaint welches auf die Windows-Nachricht WM_PAINT reagiert. In diesem Ereignis mußt du nun alle Zeichenoperationen ausführen. Sind es viele wird es flackern, da die GDI-Ausgabe relativ langsam ist. Aber deine Paintbox zeigt immer das, was sie zeigen soll. Dies ist natürlich unschön immer alles in OnPaint zu zeichnen hinzukommt, weil ja nicht immer das gleich egezeichnet werden soll. Klickt man auf den einen Button soll ein Kreis gezeichnet werden, klickt man auf den anderen ein Rechteck.
"Was tun?", sprach Zeus. Nun ganz einfach, man greift zu einem Trick. Dieser Trick besteht darin nicht direkt auf die Paintbox oder auf die Canvas des Fensters zu zeichnen, sonder auf ein Bitmap im Speichern und immer wenn nötig dieses Bitmap auf den Canvas zu kopieren. Die geschieht einmal in der ButtonClick-Prozedur und jedes mal im OnPaint Ereignis der Paintbox oder des Fensters. Das Kopieren hat auch nch den Vorteil, dass erstmal das zeichnen im Speicher schneller geht und die Ausgabe erfolgt auch schneller, da das Kopieren wesentlich schneller ist, als alles einzeln zu zeichnen.
Und weil heute Freitag ist und mir tommie-lie vorgeworfen hat, meine Antworten würden sich immer auf nötigste beschränken ein Beispiel.
Wir brauchen eine Paintbox und einen Button. Der Rest sollte sich selbst erklären.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56:
| type TForm1 = class(TForm) Button1: TButton; PaintBox1: TPaintBox; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button1Click(Sender: TObject); procedure PaintBox1Paint(Sender: TObject); private bmp : TBitmap; public end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); begin bmp := TBitmap.Create; bmp.Canvas.Brush.Color := clRed; bmp.Canvas.Pen.Width := 3; bmp.Width := Paintbox1.Width; bmp.Height := Paintbox1.Height; end;
procedure TForm1.FormDestroy(Sender: TObject); begin bmp.Free; end;
procedure TForm1.Button1Click(Sender: TObject); begin bmp.Canvas.Rectangle(5,5, 75, 75); BitBlt(PaintBox1.Canvas.Handle, 0, 0, bmp.Width, bmp.Height, bmp.Canvas.Handle, 0, 0, SrcCopy); end;
procedure TForm1.PaintBox1Paint(Sender: TObject); begin BitBlt(PaintBox1.Canvas.Handle, 0, 0, bmp.Width, bmp.Height, bmp.Canvas.Handle, 0, 0, SrcCopy); end; |
Du siehst, mit etwas Hintergrundwissen wie Windows funktioniert läßt sich ganz einfach eine Lösung für dein Problem finde, welches gar keins ist.
Ein weiters Beispiel findest du auf meiner Homepage in dem Programm "Life of Luckie". Da habe ich auch genau diese Technik angewendet. Und das TImage solltest du nicht mißbrauchen, da es für solche Zeichenaktionen nicht geschaffen wurde.