none
C++/CLR und Windows-API: Probleme mit GDI-Objekten RRS feed

  • Allgemeine Diskussion

  • Hallo zusammen,

    wenn ich mit SHGetFileInfo das Dateisymbol mit den korrekten Overlays auslese, gibt es bei RGBA-Icons Darstellungsprobleme (schwarze Ränder). Beheben konnte ich das mit dem folgenden Code:

    LIBWFM_API void __stdcall libwfm::CorrectIcon(HICON* hIcon)
    {
        ICONINFO ii;
        GetIconInfo(*hIcon, &ii);
        
        BITMAP bmp;
        GetObject(ii.hbmColor, sizeof(bmp), &bmp);
    
        Gdiplus::Bitmap temp(ii.hbmColor, NULL);
        Gdiplus::BitmapData lockedBitmapData;
        Gdiplus::Rect rc(0, 0, temp.GetWidth(), temp.GetHeight());
    
        temp.LockBits(
            &rc,
            Gdiplus::ImageLockModeRead,
            temp.GetPixelFormat(),
            &lockedBitmapData);
    
        Gdiplus::Bitmap image(
            lockedBitmapData.Width,
            lockedBitmapData.Height,
            lockedBitmapData.Stride,
            PixelFormat32bppARGB,
            reinterpret_cast<BYTE*>(lockedBitmapData.Scan0));
    
        temp.UnlockBits(&lockedBitmapData);
        
        image.GetHICON(hIcon); // <=======
    
        DeleteObject(ii.hbmColor);
        DeleteObject(ii.hbmMask);
    }

    Die markierte Zeile sorgt für ein Problem: Nach der Ausführung dieser einen Zeile (durch Auskommentieren nachvollzogen) scheinen irgendwelche GDI-Objekte nicht richtig freigegeben zu werden (konkret an meiner Anwendung, die die angegebene DLL verwendet: Wird die Zeile nicht ausgeführt, ist die Anzahl der GDI-Objekte nach Anwendungsstart 76 (diese Zahl stimmt auch mit der Anzahl der GDI-Objekte überein, sollte diese Korrekturmethode überhaupt nicht aufgerufen werden), mit Ausführung der markierten Zeile sind es 262. Ich habe schon versucht, DestroyIcon(*hIcon) aufzurufen bevor das Icon "korrigiert" wurde, allerdings ohne nennenswerten Erfolg. Scheinbar werden irgendwelche internen GDI-Handles nicht richtig entfernt. Gibt es einen bekannten Weg um dieses Problem zu beheben?
    Donnerstag, 23. Januar 2020 14:41

Alle Antworten

  • Hallo Florian,

    Es wird empfohlen, im verwalteten Code die Icon.Dispose-Methode zu verwenden. Dies ruft (intern) die DestroyIcon-Methode für Dich auf. Die Win32.DestroyIcon-Methode ist eher für die Verwendung mit Symbolen vorgesehen. Weitere Informationen findest Du im folgenden Artikel:
    Win32.DestroyIcon vs. Icon.Dispose

    Wenn Du die GetHicon-Methode und die Icon.FromHandle-Methode aufrufst, kommst Du abschließend um die Icon.Dispose-Methode und DestroyIcon-Methode nicht herum, wie hier beschrieben:
    Icon.FromHandle: should I Dispose it, or call DestroyIcon?

    Gruß,

    Ivan Dragov


    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Freitag, 24. Januar 2020 13:31
    Moderator