Mehrfachverwendung der SetPixel() funktion
-
Hallo zusammen,
ich habe folgendes Problem mit der Setpixelfunktion.Zu Beginn kann ich mit folgendem Aufruf einen Punkt bei x1,y1 zeichen.
case WM_PAINT:
hdc= BeginPaint (hwnd, &ps);
SetPixel(hdc, x1, y1, RGB(255, 0, 255));
EndPaint (hwnd, &ps);
return 0;Das funktioniert. Ich kann auch zwischen BeginnPaint und EndPaint mit Schleifen
ganze Bilder Zeichnen.
Aber danach geht die SetPixelfunktion kaputt.Wenn ich später folgendes verwende, dann passiert nichts.
case WM_Button_Down:
hdc= BeginPaint (hwnd, &ps);
SetPixel(hdc, x2, y2, RGB(255, 0, 255));
EndPaint (hwnd, &ps);
return 0;Die Button_Down Nachricht funtioniert, das habe ich ausprobiert, aber der
Punkt wird nicht gezeichnet. Was mache ich falsch?
-
sulky schrieb:
Aber danach geht die SetPixelfunktion kaputt.
Ich kann durchaus verstehen, dass bei einem Auto mal der Motor kaputt geht, aber bei SetPixel bin ich mir da nicht so sicher.Das Rendering geschieht im WM_PAINT - Ereignis. Wie schon der Name sagt.
Wenn du ueber andere Messages etwas zeichnen lassen möchtest, so kannst du dies
mitInvalidateRect(hwnd, NULL, false);
erzwingen.
Ich würde die Geschichten zum Zeichnen zentral kapseln. An jeder Stelle im Code mit BeginPaint und EndPaint zu arbeiten, find ich nicht besonders schön
-
Hallo BasicMan,
Vielen Dank für deine Antwort.
Geht das denn schneller mit InvalidateRect(hwnd, NULL, false); ?Ich will ja nicht ein Rechteck zeichnen, ausser man bezeichnet ein kleier Punkt als ein ganz kleines Rechteck.
Aber auch für das Verständnis: Wieso kann ich die SetPixelfunktion
nur in einer einzigen Nachricht verwenden und danach nicht mehr?Wenn ich in WM_Paint nichts Zeichne, so funktioniert
case WM_Button_Down:
hdc= BeginPaint (hwnd, &ps);
SetPixel(hdc, x2, y2, RGB(255, 0, 255));
EndPaint (hwnd, &ps);
return 0;Sonst nicht. Was mache ich da falsch?
-
InvalidateRect sorgt lediglich dafür, dass das WM_PAINT Ereignis ausgeführt wird und dein Fenster neu gezeichnet wird. Falls du speziell einen Bereich (2.Parameter) angegeben hast, so wird nur dieser Bereich neu gezeichnet.
InvalidateRect (auch wenn man es denken koennte) zeichnet kein Rechteck.

Das Rechteck bezeichnet nur den Bereich in deiner "ClientArea" der neu gezeichnet wird, falls du was spezielles angegebn hast)WM_PAINT wird unter anderem auch ausgelöst, wenn UpdateWindow ausgeführt wird.
Hast du also Zeichenfunktionen im WM_PAINT, so werden diese beim Start des Programmes entsprechend auch gezeichnet.sulky schrieb:
Wieso kann ich die SetPixelfunktion
nur in einer einzigen Nachricht verwenden und danach nicht mehr?Das kann ich dir nicht genau sagen. Laut MSDN wird WM_PAINT gesendet, wenn keine
anderen Messages in Nachrichtenschleife warten. Lässt man sich mal nach Programmstart ausgeben, wann ein WM_PAINT ausgelöst wird (z.B. durch Ausgabe auf der Konsole) ohne irgendwas darin zu zeichnen, so wird ununterbrochen diese Message ausgelöst.
Erst mit einem Aufruf durch BeginPaint wird dies unterbrochen.
Danach lässt sich WM_PAINT nur durch bestimmte Aktionen oder Befehle auslösen.vielleicht sollte man den Thread mal ins WinApi Forum rüberschieben

-
Ich beschreibe das mal so:
hdc= BeginPaint (hwnd, &ps);
SetPixel(hwnd,100,100,RGB(0,0,255))
EndPaint (hwnd, &ps);Macht einen Blauen Punkt bei 100,100
jedoch der (unsinnige) Befehl
hdc= BeginPaint (hwnd, &ps);
EndPaint (hwnd, &ps);
hdc= BeginPaint (hwnd, &ps);
SetPixel(hwnd,100,100,RGB(0,0,255))
EndPaint (hwnd, &ps);Macht überhaupt nichts. Ich habe auch folgendes ausprobiert:
hdc= BeginPaint (hwnd, &ps);
hdc= BeginPaint (hwnd, &ps);
SetPixel(hwnd,100,100,RGB(0,0,255))
EndPaint (hwnd, &ps);Auch dieser Punkt wird nicht gezeichnet. Die BeginPaint-Funktion macht offensichtlich irgendetwas, was ich nicht verstehe. Kannst du mir das erklären?
-
das hab ich mit meinem bescheidenen Wissen doch schon versucht:Ich selbst schrieb:
Das kann ich dir nicht genau sagen. Laut MSDN wird WM_PAINT gesendet, wenn keine
anderen Messages in Nachrichtenschleife warten. Lässt man sich mal nach Programmstart ausgeben, wann ein WM_PAINT ausgelöst wird (z.B. durch Ausgabe auf der Konsole) ohne irgendwas darin zu zeichnen, so wird ununterbrochen diese Message ausgelöst.
Erst mit einem Aufruf durch BeginPaint wird dies unterbrochen.
Danach lässt sich WM_PAINT nur durch bestimmte Aktionen oder Befehle auslösen.zur weiteren Erklärung kann ich dir leider nicht helfen, da bin ich zu viel Amateur. Will dir ja auch nichts falsches erzählen. Aber wie schon erwähnt, kannst du das Problem umgehen, indem du deine Zeichenfunktionen zentral verwaltest.
struct Pixel { int x,y; Pixel(): x(0), y(0) {}; } myPixel; // eine zentrale Zeichenfunktion void paint(HWND hWnd) { hdc = BeginPaint (hWnd, &ps); SetPixel(hdc, myPixel.x, myPixel.y, RGB(255, 0, 255)); EndPaint( hWnd, &ps ); } case WM_PAINT: { // zeichenfunktion nur hier aufrufen paint(hWnd); return 0; } break; case WM_LBUTTONDOWN: { // an anderen Stellen deine Daten veraendern myPixel.x += 10; myPixel.y += 10; // WM_PAINT ausloesen InvalidateRect(hWnd, NULL , false); } break;//Edit: denk dran, wenn du das gesamte Fenster neu zeichnest,dass du auch alle gesetzten Pixel irgendwo vorhalten musst. Schiebst du dein Fenster aus der Monitorbegrenzung, dann verschwinden die natürlich
Aber das ist ja ein anderes Thema und hat mit dem Problem nichts zu tun.
-
man kann schon auch zeichnen ohne ein WM_PAINT erhalten zu haben.
man muss sich den DC nur anders besorgen.
-
ok, jetzt habe ich einen Weg gefunden, um das Problem zu lösen.
Vielen Dank Basicman
-
kann mir kurz jemand Sagen welches Framework das ist? Es ist nämlich sicher kein Standard-C++ udn deshalb mal wieder im falschen Forum...

-
pumuckl schrieb:
kann mir kurz jemand Sagen welches Framework das ist? Es ist nämlich sicher kein Standard-C++ udn deshalb mal wieder im falschen Forum...

Win32 API
-
Dieser Thread wurde von Moderator/in pumuckl aus dem Forum C++ in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.