| |||||||||||||||||||||||||||||||
|
|
|
|
Wurde bisher nur die Erstellung und das Schließen eines Fensters aufgezeigt, so soll nun der prinzipielle Ablauf bei der Darstellung des Fensterinhalts betrachtet werden.
Wenn WINDOWS entweder das ganze Fenster oder einen Teil davon neu zeichnen lassen möchte, so sendet es eine Nachricht WM_PAINT. Die Zusatzinformationen zur Nachricht haben folgende Bedeutung:
WM_PAINT Nachricht |
|
| WPARAM wParam | keine Bedeutung |
| LPARAM lParam | keine Bedeutung |
Beachten Sie bitte, dass die Fensterprozedur im Parameter hWnd das Fenster-Handle des Fensters erhält, dessen Inhalt zu aktualisieren ist.
Merken Sie sich aber für alle Zeiten folgenden wichtigen Satz:
| Ein WINDOWS Programm muss jederzeit in der Lage sein den Inhalt seines Fensters neu darzustellen. WINDOWS selbst speichert den Inhalt eines Fenster nicht ab! |
Um das Fenster auf das Zeichnen (und darunter fällt auch die Ausgabe von Texten, denn WINDOWS ist ein grafisches System) seines Inhaltes vorzubereiten, muss zuerst die Funktion BeginPaint(...) aufgerufen werden. Sie liefert als Returnwert ein Handle auf einen Device Context den jede Zeichenoperation benötigt. Der Device Context enthält alle aktuellen Einstellungen die für das Zeichnen benötigt werden. Darunter fällt z.B. der aktuelle Pen (Zeichenstift) oder auch der aktuelle Brush (Pinsel).
Außer diesem Device-Context-Handle liefert die Funktion BeginPaint(...) auch den Bereich innerhalb des Fensters zurück, innerhalb dessen gezeichnet wird. Zeichenoperationen die außerhalb dieses Bereichs liegen werden unterdrückt. Dieser Bereich wird auch als Clipping-Bereich bezeichnet.
| Beispiel: | Die Client-Area des
Fensters besitzt eine Ausdehnung von 150x150 Pixel. Daraus folgt, dass das Fenster die
Koordinaten von (0/0) bis (149/149) besitzt. Nehmen wir jetzt an, dass der
Clipping-Bereich von (50/50) bis (100/100) gehen soll. Wird jetzt versucht eine Linie von
links oben (0/0) nach rechts unten (149/149) zu zeichnen, so wird die Linie nur im Bereich
von (50/50) bis (100/100) neu gezeichnet. Der darüber hinausgehende Teil der Linie wird
beim Zeichnen abgeschnitten.
|
Nach dem Aufruf von BeginPaint(...) kann die Anwendung dann mit Hilfe des erhaltenen Device Context Handle den Fensterinhalt neu darstellen.
Ist der Fensterinhalt aktualisiert worden, muss die Anwendung das Gegenstück zu BeginPaint(...) aufrufen, die Funktion EndPaint(...). EndPaint(...) kennzeichnet den gesamten Fensterinhalt als gültig, d.h. der Clipping-Bereich wird geleert.
Doch woher weiß WINDOWS, welcher Bereich im Fenster ungültig ist und damit neu gezeichnet werden muss? Um diese Frage zu beantworten müssen wir drei Fälle unterscheiden:
![]() |
![]() |
| vorher | nachher |
![]() |
![]() |
| vorher | nachher |
Mit dem jetzt erworben Wissen könnten wir das vorherige Beispiel um die Bearbeitung der WM_PAINT Nachricht erweitern. Was zum Schluss noch fehlt, ist das eigentliche Zeichnen als Reaktion auf die Nachricht. Dies wird aber erst später im Kapitel GDI behandelt. Damit im Beispiel trotzdem festgestellt werden kann wann eine WM_PAINT Nachricht eintrifft, geben wir als Reaktion auf die Nachricht einen Ton aus. Dies kann durch den Aufruf der Funktion MessageBeep(...) erreicht werden.
Fügen Sie jetzt zu Ihrer Fensterprozedur die Verarbeitung der WM_PAINT
Nachricht hinzu. Da wird ja noch nichts zeichnen können, rufen Sie statt dessen die
Funktion MessageBeep(-1UL) auf.
Wenn Sie das Beispiel laufen lassen spielen Sie auch einmal mit dem Fenster. Beobachten Sie wann eine WM_PAINT Nachricht ausgelöst wird und wann nicht. Kommentieren Sie zu Versuchszwecken die beiden Aufrufe von BeginPaint(...) und EndPaint(...) einmal aus. Wenn Sie das Programm erneut starten, werden Sie laufend WM_PAINT Nachrichten empfangen. Warum? Nun, erst durch den Aufruf von EndPaint(...) wird der Fensterinhalt wieder als gültig gekennzeichnet. Und solange Sie dies nicht tun sendet WINDOWS ständig weitere WM_PAINT Nachrichten an das Fenster damit es seinen Inhalt als gültig markieren kann. |
Noch eine kleine Frage am Rande: Wenn das Fenster beim Auskommentieren von BeginPaint(...) und EndPaint(...) ständig WM_PAINT Nachrichten erhält, warum kann es dennoch geschlossen werden, d.h. warum erhält das Fenster trotzdem eine WM_CLOSE bzw. WM_DESTROY Nachricht? Der Grund dafür ist, dass WINDOWS Nachrichten priorisiert, und die WM_PAINT Nachricht hat eine relativ niedrige Priorität. Solange das Fenster noch andere Nachrichten zu verarbeiten hat wird die WM_PAINT Nachricht ganz einfach zurückgehalten.
Und zum Schluss noch ein ganz wichtiger Hinweis:
| ACHTUNG! Setzen Sie NIEMALS innerhalb des Bearbeiters für die WM_PAINT Nachricht mit
dem Debugger einen Breakpoint. Läuft der Debugger nämlich auf diesen Breakpoint und
hält das Programm an, so wird das Debugger-Fenster in den Vordergrund gebracht. Dadurch
wird aber der Fensterinhalt des zu untersuchenden Programms sofort wieder ungültig und
das Fensters erhält umgehend eine weitere WM_PAINT zugesandt. Das gleiche gilt übrigens auch wenn Sie im Verarbeitungszweig der WM_PAINT Nachricht versuchen eine Messagebox darzustellen. |
Im nächsten und letzten Praxisschritt in diesem Kapitel werden wir uns noch ansehen was beim Verändern der Fenstergröße so alles passiert.
|
|
|
|
|
|