Probleme/Fragen zu WM_PAINT und BeginPaint()
-
Hallo...
ich hoffe mal, dass ich das richtige Forum für meine Fragen erwischt hab...
Bin noch blutiger Anfänger bei WinAPI-Geschichten, versuche z.Zt. das anhand eines Anfängerbuches zu lernen und hab dabei ein paar (kleine) Verständnisprobleme:1. Mein "Hauptproblem": Ich hab ne Funktion programmiert, mit der bei Mausklick (WM_LBUTTONCLK) ein Text mit TextOut() an der angeklickten Stelle ausgegeben wird. Wenn ich die Größe des Fensters ändere, ist der Text wieder weg. Was muss ich tun, damit er da bleibt? Brauch jetzt keinen Code dazu, den bastel ich mir lieber selbst, sondern eher ein paar grobe Hinweise...
2. Was genau ist WM_Paint? Also wer übergibt wann und warum diese Nachricht an meine Nachrichtenschleife? Und wozu ist das gut?
3. Wozu braucht man BeginPaint() ? Meine Rectangle-Rechtecke werden auch so gezeichnet..? Und warum steht in dem Buch, dass man BeginPaint() nur bei WM_Paint nutzen sollte?
Das Buch ist teilweise etwas zu oberflächlich und auch beim googlen bin ich gescheitert (schlechte Englischkenntnisse
) Deshalb versuch ichs hier - wär nett, wenn mir jemand weiterhelfen könnte...
-
Mit WM_PAINT teilt das System Deiner Anwendung mit, dass ein Fensterbereich neu gezeichnet werden muss. Mit BeginPaint erhältst Du einen passenden Device-Context, in dem nur der neuzuzeichnende Bereich beschrieben werden kann (Stichwort "Region" - so wird z. B. vermieden, dass nicht veränderte Bereiche neu gezeichnet werden (führt u. U. zu "Flimmern").
Um Deinen Text dauerhaft ins Fenster zu bekommen, speicherst Du ihn in eine Variable, teilst dem System mittels InvalidateRect() mit, dass sich der Fensterinhalt ändern soll und zeichnest dann in der WM_PAINT-Message den Inhalt der Variablen ins Fenster.
-
WM_PAINT ist die Nachricht, mit der das Betriebssystem dem Programm mitteilt, daß das Fenster neu gezeichnet wird. Das passiert immer, wenn sich an dem Fenster etwas geändert hat (Größe, Überlappung durch andere Fenster).
In der Standardbearbeitung wird dann nur der Fensterinhalt mit der Hintergrundfarbe ausgefüllt. Deswegen verschwindet Dein Text.Alle Zeichenoperationen, die bei einer Fensteränderung erhalten bleiben sollen, müssen bei der WM-PAINT bearbeitet werden. Zeichnen kann man auch anderswo, aber solche Änderungen gehen verloren.
Du mußt nach WM_LBUTTONCLK die Koordinaten des Mauszeigers (in LOWORD/HIWORD(wParam) in Variablen ablegen, den Text ebenfalls. Beides kannst Du dann bei WM_PAINT ausgeben.
Hier noch ein paar schöne Tutorials:
http://www.win-api.de/
http://pronix.linuxdelta.de/C/win32/index.shtml
-
Danke Euch beiden für die Antworten und die Links
Den Sinn von WM_PAINT hab ich jetzt erstmal kapiert - und das Speichern... naja, da üb ich noch ;), aber Prinzip ist erstmal klarEine Nachfrage hab ich aber noch: ich hol mir mein HDC mit GetDC() und kann damit auch zeichnen - zumindest ging es bei meinen bisherigen - einfachen - Übungen. Hat BeginPaint demgegenüber irgendeinen Vorteil oder ist das einfach nur Geschmacksache, wie man's macht?
-
Naja, wie schon gesagt: BeginPaint ist die Antwort auf die WM_PAINT-Nachricht. BeginPaint wird daher eigentlich nur unter WM_PAINT verwendet. Dafür bleiben Deine Fensterinhalte eben stehen.
BeginPaint() liefert automatisch einen HDC zurück. Das erspart einen Zwischenschritt. Deshalb schreibt man bei der Funktion:HDC hDC; PAINTSTRUCT ps; //(...) hDC = BeginPaint(hWnd, &ps);//Damit wird der DeviceContext dem Fenster zugewiesen. //Die Struktur ps (Typ PAINTSTRUCT)liefert Daten für die Ablage der Fensterinhalte. { //Hier Deine Ausgabefunktionen } EndPaint(hWnd, &ps);
-
Elektronix schrieb:
Alle Zeichenoperationen, die bei einer Fensteränderung erhalten bleiben sollen, müssen bei der WM-PAINT bearbeitet werden. Zeichnen kann man auch anderswo, aber solche Änderungen gehen verloren.
Sinnvoller wäre es immer in ein Bitmap im speicher zu malen und dies bei Bedarf neu auf den Canvas zu blitten. Wenn mal viel zeichnet ist diese Vorgehensweise um einiges schneller als immer alles neu zu zeichnen.
-
@Gast Luckie
Mag sein. Aber 1. ist "Schaf77" Neueinsteiger- wie sich aus der Eingangsfrage ersehen läßt- und diese Methode für Anfänger wohl noch etwas hoch, 2. wissen weder er noch ich, was "auf den Canvas zu blitten" bedeutet und wie man das macht.
:pWenn Du ein Tutorial dazu kennst, wär's natürlich klasse.

-
Puh, da bin ich ja echt beruhigt, dass ich das Canvasgeblittere nicht verstehen muss

@Elektronix:
Da du so schön erklären kannst (danke nochmal), hab ich noch ne klitzekleine Frage zu den Nachrichten: wie bekomm ich denn da eine UND-Verknüpfung hin? Also konkret: ich kenne WM_LBUTTONCLK und WM_MOUSEMOVE(
), aber welche Nachricht ist "Bewegen bei gedrückter Maustaste"?? Da ja jede Nachricht einzeln kommt (vermute ich mal) kann ich das ja schlecht mit && machen, oder?
-
schaf77 schrieb:
Puh, da bin ich ja echt beruhigt, dass ich das Canvasgeblittere nicht verstehen muss

@Elektronix:
Da du so schön erklären kannst (danke nochmal)...,Danke für die Blumen..

Zu Deiner Frage. Bei WM_MOUSEMOVE wird in wParam der Status der Tasten gespeichert. Siehe hier:
-
Aaah
da werd ich wohl doch erstmal ordentlich die Tutorials durcharbeiten.
Thx... bis zur nächsten Frage