Speicher überfüllt - Programm stürzt ab



  • Mein Code:

    HDC hDC2 = BeginPaint(hwnd, &ps);
    HDC hDC = CreateCompatibleDC(hDC2);
    HBITMAP hBM = CreateCompatibleBitmap(hDC2,200,200);
    SelectObject(hDC,hBM);
    FillRect(hDC,&hwndRect,(HBRUSH)GetStockObject(BGCOLOR))
    
    //Hier sind die verschiedenen TextOuts und so...
    
    EndPaint(hwnd,&ps);
    temp = BitBlt(hDC2,0,0,200,200,hDC,0,0,SRCCOPY);
    DeleteObject(hBM);
    DeleteDC(hDC);
    DeleteDC(hDC2);
    

    Nach ner gewissen Zeit stürzt mein Spiel immer ab. Ich glaube, weil der Speicher überfüllt ist. Wenn ich die Methode wieder auf Single Buffering umstelle habe ich das Problem nicht.

    mfg



  • hDC2 darfst du nicht mit DeleteDC() löschen. hDC2 wurde mit BeginPaint() erstellt, wird also bei EndPaint() automatisch zerstört.
    Außerdem ist hDC2 nach EndPaint bereits ungültig, das heißt du musst das BitBlt vor EndPaint ausführen.



  • Du kannst die Sachen wohl nicht löschen, wenn du sie nicht vorher mit SelectObject rausselektierst (Rückgabewert beachten).



  • Ringding schrieb:

    Du kannst die Sachen wohl nicht löschen, wenn du sie nicht vorher mit SelectObject rausselektierst (Rückgabewert beachten).

    IMHO muss man ein selektiertes HBITMAP nicht durch das alte ersetzen, man darf es gleich mit DeleteObject löschen.



  • cd9000 schrieb:

    hDC2 darfst du nicht mit DeleteDC() löschen. hDC2 wurde mit BeginPaint() erstellt, wird also bei EndPaint() automatisch zerstört.
    Außerdem ist hDC2 nach EndPaint bereits ungültig, das heißt du musst das BitBlt vor EndPaint ausführen.

    Wenn ich das mache, also EndPaint nach BitBlt setze, wird das Bild nicht mehr aktualisiert.

    Wie geht das mit dem Selectieren? Ich kanns ja mal ausprobieren..

    PS: Was heißt IMHO???



  • joomoo schrieb:

    Wenn ich das mache, also EndPaint nach BitBlt setze, wird das Bild nicht mehr aktualisiert.

    Zeig mal bitte den Code, der nicht funktioniert. Tatsache ist, dass EndPaint am Ende und nicht mittendrin stehen sollte, zumindest wenn du hDC2 noch benutzen willst.

    joomoo schrieb:

    Wie geht das mit dem Selectieren? Ich kanns ja mal ausprobieren..

    SelectObject? Das benutzt du doch schon?
    Ringding meinte, dass du das alte HBITMAP speichern und am Ende wieder reinselektieren sollst.

    joomoo schrieb:

    PS: Was heißt IMHO???

    Google. HTH 🙂



  • HDC hDC2 = BeginPaint(hwnd, &ps);
    HDC hDC = CreateCompatibleDC(hDC2);
    HBITMAP hBM = CreateCompatibleBitmap(hDC2,200,200);
    SelectObject(hDC,hBM);
    FillRect(hDC,&hwndRect,(HBRUSH)GetStockObject(BGCOLOR))
    
    //Hier sind die verschiedenen TextOuts und so...
    
    temp = BitBlt(hDC2,0,0,200,200,hDC,0,0,SRCCOPY);
    EndPaint(hwnd,&ps);
    DeleteObject(hBM);
    DeleteDC(hDC);
    

    Wie kann ich den das alte HBITMAP wieder selektieren?



  • Ringding schrieb:

    Du kannst die Sachen wohl nicht löschen, wenn du sie nicht vorher mit SelectObject rausselektierst (Rückgabewert beachten).

    Könntest du mir das in den Code einbauen? Ich hab keine Ahnunge wie das gehen soll.

    mfg



  • joomoo schrieb:

    DeleteObject(hBM);
    DeleteDC(hDC);
    

    ...möglicherweise haut das auch nicht hin.
    DeleteObject() könnte fehlschlagen, weil die bitmap sich noch in hDC befindet.
    eventuell beide aufrufe vertauschen - oder...
    ...der richtige weg wäre:
    1. beim SelectObject() sich den rückgabewert merken
    2. hdc benutzen
    3. fertig: SelectObject() für den hdc mit dem vorher gemerkten wert aufrufen

    dann ist das bitmap-handle frei und kann auf jeden fall gelöscht werden.

    uhhhmm... da waren andere wieder schneller 😞



  • net schrieb:

    joomoo schrieb:

    DeleteObject(hBM);
    DeleteDC(hDC);
    

    ...möglicherweise haut das auch nicht hin.
    DeleteObject() könnte fehlschlagen, weil die bitmap sich noch in hDC befindet.
    eventuell beide aufrufe vertauschen - oder...
    ...der richtige weg wäre:
    1. beim SelectObject() sich den rückgabewert merken
    2. hdc benutzen
    3. fertig: SelectObject() für den hdc mit dem vorher gemerkten wert aufrufen

    dann ist das bitmap-handle frei und kann auf jeden fall gelöscht werden.

    uhhhmm... da waren andere wieder schneller 😞

    Und wie sieht der Code dafür aus? Könntest du mir das in meinen Code reinschreiben oder mir die Befehle sagen?

    mfg



  • net schrieb:

    1. beim SelectObject() sich den rückgabewert merken
    2. hdc benutzen
    3. fertig: SelectObject() für den hdc mit dem vorher gemerkten wert aufrufen

    joomoo schrieb:

    Und wie sieht der Code dafür aus? Könntest du mir das in meinen Code reinschreiben oder mir die Befehle sagen?

    Ich bitte um etwas Eigeninitiative, net hat doch jeden Schritt präzise beschrieben. 🙄
    Ein Anfang wäre es z.B. in die Doku zu SelectObject() zu schauen, damit du weißt, was die Funktion überhaupt macht.



  • cd9000 schrieb:

    net schrieb:

    1. beim SelectObject() sich den rückgabewert merken
    2. hdc benutzen
    3. fertig: SelectObject() für den hdc mit dem vorher gemerkten wert aufrufen

    joomoo schrieb:

    Und wie sieht der Code dafür aus? Könntest du mir das in meinen Code reinschreiben oder mir die Befehle sagen?

    Ich bitte um etwas Eigeninitiative, net hat doch jeden Schritt präzise beschrieben. 🙄
    Ein Anfang wäre es z.B. in die Doku zu SelectObject() zu schauen, damit du weißt, was die Funktion überhaupt macht.

    Ich habs schon alles probiert doch es klappt alles nicht. Wie soll ich denn den Rückgabewert speichern? Ich habs in nen Zeiger gespeichert, aber das klappt nicht. Wenn ich den Code wüsste, würde ich dann fragen.



  • schau ma in die msdn da steht auch der rückgabetyp der funktion, und wie speichert man den rückgabewert einer funktion? richtig, indem man den rückgabewert in einer variable des selben typs mittels eines "=" operators speichert.eine tolle erkenntnis oder? 😮

    falls du die msdn nich findest:

    HGDIOBJ SelectObject(
    HDC hdc, // handle to DC
    HGDIOBJ hgdiobj // handle to object
    );

    🙄



  • Mein Script sieht jetzt so aus:

    HDC hDC2 = BeginPaint(hwnd, &ps);
    HDC hDC = CreateCompatibleDC(hDC2,200,200);
    HBITMAP hBM = CreateCompatibleBitmap(hDC2,200,200);
    HGDIOBJ hOldBM = SelectObject(hDC, hBM);
    FillRect(hDC,&hwndRect,(HBRUSH)GetStockObject(BGCOLOR));
    
    //TextOuts und sowas...
    
    temp = BitBlt(hDC2,0,0,200,200,hDC,0,0,SRCCOPY);
    temp = EndPaint(hwnd, &ps);
    SelectObject(hDC,hOldBM);
    DeleteDC(hDC);
    DeleteObject(hBM);
    InvalidRect(hwnd,&hwndRect,FALSE);
    

    Doch leider aktualisiert sich das Bild nicht. Ich sehe das ´Bild von Menü, nur wenn ich neu zeichne ändert sich nichts.



  • Wird der Code, den du gepostet hast, ausschließlich bei WM_PAINT aufgerufen?



  • cd9000 schrieb:

    Wird der Code, den du gepostet hast, ausschließlich bei WM_PAINT aufgerufen?

    nein



  • joomoo schrieb:

    cd9000 schrieb:

    Wird der Code, den du gepostet hast, ausschließlich bei WM_PAINT aufgerufen?

    nein

    Dann hast du den Fehler gerade gefunden.


Log in to reply