Grafikfehler der GDI

Technipion

Erfahrenes Mitglied
Hallo liebe Community,
ich schreibe in meiner Freizeit oft viele kleine Programme, die ich dann auch privat und für die Schule nutze. Das Problem ist, dass sich bei allen diesen Programm ständig ein Fehler einschleicht, den ich mir nicht erklären kann...
Ich habe bereits gefühlte 400 mal das ganze Internet abgesucht... aber leider bin ich nicht fündig geworden.
Ich hoffe einer der Experten unter euch kann mir helfen:

Um in die Fenster zu zeichnen benutze ich die Windows GDI. Im WM_PAINT case der Fensterklassen erstelle ich zuerst eine Bitmap und zeichne dann in diese. Im letzten Schritt übertrage ich die Bitmap 1:1 auf den Bildschirm.

Code:
case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
            HDC hdcMemory;
            HBITMAP hBitmap;
            RECT rc;
            GetClientRect(hwnd, &rc);
            hdcMemory = CreateCompatibleDC(hdc);
            hBitmap = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
            SelectObject(hdcMemory, hBitmap);
            PatBlt(hdcMemory, rc.left, rc.top, rc.right, rc.bottom, WHITENESS);
            //
            //Zeichne hier etwas
            //
            BitBlt(hdc, rc.left, rc.top, rc.right, rc.bottom, hdcMemory, 0, 0, SRCCOPY);
            ReleaseDC(hwnd, hdc);
            DeleteObject(hBitmap);
            EndPaint(hwnd, &ps);
            break;
Wenn ich das Programm starte, ist normal alles in Butter. Aber lässt man das Programm einfach ein paar Minuten laufen (und so etwas sollte ein Programm nunmal können!), dann fängt die Grafik an zu spinnen. Auf einmal sind Punkte und Linien da, wo sie nicht hingehören, und jene die da sein sollten fehlen!
Zuerst dachte ich es liegt vielleicht an dem Bitmap-Puffer, aber wenn ich die gleiche Grafik direkt ins Fenster zeichne, passiert das sogar noch schneller!

Ich hoffe einer von euch versteht warum Windows diesen hässlichen "Grafikfehler" produziert.

Danke schonmal im Voraus
Gruß Technipion
 
Bei GDI-Objekten gibt es zwei Varianten der Erstellung, da muß immer die passende Abbau-Funktion benutzt werden. Alles mit Create benötigt ein Delete, alles mit Get ein Release.

D.h. für hdcMemory fehlt ein DeleteDC.
Den hdc von BeginPaint gibst du mit EndPaint frei, da darfst du nicht auch noch ReleaseDC verwenden.
Man sollte, auch bei temporären HDCs, das alte, per SelectObject rausgewählte Objekt wieder einsetzen:

HBITMAP hOldBitmap = SelectObject( hdcMemory, hBitmap);

// benutzen

SelectObject( hdcMemory, hOldBitmap );


Wenn du in WM_PAINT bereits alles darstellst, dann sollte man 0 zurückgeben, und nicht mehr an DefWindowProc aufrufen.
 
Hey Endurion,
ich habe mir deine Tipps zu Herzen genommen und mein Programm umgeformt.
Ich zeichne jetzt allerdings im WM_TIMER case.
Es hat auch super funktioniert, das Programm braucht jetzt 5 mal so lange bis es anfängt zu spinnen, außerdem ist jeder punkt noch da wo er sein soll.
Bloß habe ich jetzt das Problem, dass mein PC nach etwa 2 Minuten Laufzeit alles bloß noch schwarz-weiß darstellt...
Ich glaube langsam es liegt an meinem OS******
Hast du noch einen Tipp?
Wenn nicht ist auch gut, danke nochmals für die Hilfe.
Gruß Technipion
 
Zurück