DeleteObject() in WM_PAINT + Win98



  • Hi,
    Warum verursacht folgender Code, schwere Fehler unter Win98 und unter WinXP nicht, was muss ich ändern, damit keine Fehler mehr auftauchen, bei den verschiedenen Stiften ????

    HDC                hdc ;
    HPEN               hPen;
    
    //......
     case WM_PAINT:
              hdc = BeginPaint (hwnd, &ps) ;
    
                  hPen=CreatePen(PS_SOLID,1,RGB(155,155,155));
              SelectObject(hdc, hPen);
              Polyline(hdc,apt,points); // Graph ausgeben         DeleteObject(SelectObject(hdc,hPen)); 
    
              hPen=CreatePen(PS_SOLID,1,RGB(0,0,225));
              SelectObject(hdc, hPen);
              Polyline(hdc,apt2,points); // Graph ausgeben        DeleteObject(SelectObject(hdc,hPen)); 
    
              hPen=CreatePen(PS_SOLID,1,RGB(225,0,0));
              SelectObject(hdc, hPen);
              Polyline(hdc,apt3,points); // Graph ausgeben  
    DeleteObject(SelectObject(hdc,hPen)); 
    
    EndPaint (hwnd, &ps) ;
              return 0 ;
    

    MfG Unwissender 🙂



  • Probiers mal so:

    // Penspeichern, der derzeit in den DC selektiert ist
    hOldPen = SelectObject(hdc, CreatePen(PS_SOLID,1,RGB(155,155,155)) );
    Polyline(hdc,apt,points);
    
    // neuen Pen hinein-selektieren und alten löschen
    DeleteObject( SelectObject( hdc,CreatePen(PS_SOLID,1,RGB(0,0,225)) ) );
    Polyline(hdc,apt2,points);
    
    // neuen Pen hinein-selektieren und alten löschen
    DeleteObject( SelectObject( hdc,CreatePen(PS_SOLID,1,RGB(225,0,0)) ) );
    Polyline(hdc,apt3,points);
    
    // gespeicherten Pen wieder zurück selektieren und alten löschen
    DeleteObject( SelectObject( hdc,hOldPen) );
    


  • @flenders

    Ich dachte schon das es funzt doch leider 😞 - es scheint an der Schrift zu liegen die ich zweimal ändere - hier der Code:

    // Funktion welche in nach BeginPaint aufgerufen wird
    LOGFONT     lf;
    HFONT       hFont;
    HPEN        hPen;
    .....
    lf.lfEscapement = lf.lfOrientation = 0; // 0° Grad einstellen !
              lf.lfHeight = 11; 
    
              SelectObject(hdc,hFont = CreateFontIndirect(&lf)); // Font einstellen 
    
              TextOut(hdc,635,15,"Arbeitsspeicher",lstrlen("Arbeitsspeicher"));           TextOut(hdc,635,30,"Texturspeicher",lstrlen("Texturspeicher"));         TextOut(hdc,635,45,"Video-Speicher",lstrlen("Video-Speicher")); 
    
    DeleteObject(SelectObject(hdc,hFont)); // auch DeleteObject(SelectObject(hdc,CreateFontIndirect(&lf))); geht nicht
    
    memset(&lf, 0, sizeof(LOGFONT));  // Initialisieren indem Fall leeren !
              lf.lfEscapement = lf.lfOrientation = -900 ; // 90° Grad drehen
              lf.lfHeight = 11; 
              DeleteObject(SelectObject(hdc,hFont=CreateFontIndirect(&lf)));
    //Schleife blab ...........
    TextOut(hdc,i+7,588,szString,lstrlen(szString));
    
    DeleteObject(SelectObject(hdc,hFont)); 
    //zurück zu WM_PAINT
    

    MfG Unwissender 🙂

    Ps: Der Fehler tritt erst nach einer Weile auf - mehreren Sekunden -> Neuzeichnungen



  • SelectObject(hdc,hFont = CreateFontIndirect(&lf)); // Font einstellen
    ^^^^
    SelectObject() gibt immer das Object zurück, was vorher (also in diesem Falle vor der Schriftart) in den DeviceContext selektiert war - Das musst Du unbedingt speichern und wenn du mit dem aktuellen Object (dem Font) fertig bist wieder reinselektieren! Sonst gibts Speicherlecks und die GDI-Resourcen gehen in den Keller und irgendwann beginnt das System dann Grafikfehler zu produzieren...

    Also generell:

    HGDIOBJ altesObject; // HGDIOBJ kann ein HBRUSH, HFONT, etc sein...
    HBRUSH beispielObject; // Nehmen wir als Beispiel mal nen Brush...
    
    beispielObject=CreateSolidBrush(RGB(0,0,0)); // Nen schwarzen Brush erzeugen
    
    // Altes Object speichern (was auch immer das ist) und neues rein-selektieren:
    altesObject=SelectObject(DeviceContext,beispielObject);
    
    // Irgendwas mit dem Brush machen
    ...
    
    // So, jetzt will ich ne anderes Object, z.B. nen Font
    // Altes Object wieder reinselektieren, Rückgabewert ist ja jetzt das HBRUSH, welches ich löschen kann:
    DeleteObject( SelectObject(DeviceContext,altesObject) );
    
    // so, jetzt kann ich dasselbe wie oben mit nem HFONT oder was anderem machen..
    


  • danke für die tolle erklärung 🙄



  • Das sieht ja füchterlich aus 😮
    Ich hab zwar gerade nicht genau im Kopf wie das mit den Schriftarten war, aber probier es mal so:

    HGDIOBJ hOldObject = SelectObject(hdc,CreateFontIndirect(&lf)); // Font einstellen und altes Objekt speichern
    
    TextOut(hdc,635,15,"Arbeitsspeicher",lstrlen("Arbeitsspeicher"));
    TextOut(hdc,635,30,"Texturspeicher",lstrlen("Texturspeicher"));
    TextOut(hdc,635,45,"Video-Speicher",lstrlen("Video-Speicher"));
    
    memset(&lf, 0, sizeof(LOGFONT));  // Initialisieren indem Fall leeren !
    lf.lfEscapement = lf.lfOrientation = -900 ; // 90° Grad drehen
    lf.lfHeight = 11; 
    // neuen Font einstellen und gleichzeitig vorherigen Font löschen
    DeleteObject(SelectObject(hdc,CreateFontIndirect(&lf))); 
    
    //Schleife blab ...........
    TextOut(hdc,i+7,588,szString,lstrlen(szString));
    
    DeleteObject(SelectObject(hdc,hOldObject)); // ursprüngliches Objekt wieder zurückselektieren und 2. Font löschen!
    //zurück zu WM_PAINT
    

    [ Dieser Beitrag wurde am 29.12.2002 um 11:44 Uhr von flenders editiert. ]



  • @geeky & @flenders

    Vielen vielen Dank für die Erklärungen - jetzt weiss ich wie ich damit arbeiten muss 😉
    Und es scheint auch zu funktionieren 🙂 *freu*

    MfG Unwissender 🙂


Anmelden zum Antworten