CImageList funzt nicht richtig



  • Hallo Leute!

    Habe ein Problem mit der CImageList. Bin gerade dabei, mir einen kleinen Explorer zu programmieren. Habe dabei allerdings mit der CImageList ein Problem. Und zwar habe ich mir von CListCtrl eine Klasse abgeleitet, die eine Membervariable vom Typ CImageList enthält. Ich erstelle in einer Init Funktion die ImageList mit

    m_ImageList.Create(GetSystemMetrics(SM_CXSMICON),
               GetSystemMetrics(SM_CYSMICON),
               ILC_COLOR24, 50, 50);
    m_ImageList.SetBkColor(GetSysColor(COLOR_WINDOW));
    SetImageList(&m_ImageList, LVSIL_NORMAL);
    

    Dann lese ich die Dateien von der Festplatte mit der Funktion SHGetFileInfo aus und hole mir den Handle auf das Icon der Datei. Dann füge ich das Icon mit

    iIcon = m_ImageList.Add(shFileInfo.hIcon); // Icon der ImageList hinzufügen
    

    der ImageList hinzu und setzte den Dateinamen und das Icon in meine Listenklasse hinzu

    InsertItem(iItemNr, strFileName, iIcon);
    

    Wenn ich jetzt den Pfad änder, lösche ich die ImageListe wieder mit

    for (int i = m_ImageList.GetImageCount(); i >= 0; i--){
        m_ImageList.Remove(i);} // Komplette ImageList wieder löschen
    

    Soweit funzt es ja auch. Aber wenn ich in der ImageListe mehrere male Icons erstellt habe und diese wieder lösche und dann wieder welche hinzufüge (so bei ca 4000 Icons) dann werden diese Icons nicht mehr dargestellt. Also, ich meine: Ich habe in der ImageList z.B. nur 100 Icons, aber insgesamt wurden ca. 4000 Icons erstellt und wieder gelöscht, und danach funzt es nicht mehr. Was mache ich falsch? Ich Versuche den Fehler schon seit Tagen weg zu bekommen.



  • Was machst Du:

    -Erstelle Auto
    -Stelle Auto in Ampelschlange
    -hole Auto aus Ampelschlange

    Hm, warum verringert sich nicht die Anzahl der Autos??
    Richtig, Du musst das Auto auch wieder zerstören!



  • Was meinst Du damit?

    Ich lösche das Icon doch aus der ImageList mit Remove. Oder ist das Falsch? Was soll ich denn sonst machen, um das Icon aus der Liste zu löschen? Bin noch nicht so lange mit der MFC am programieren.
    Wenn ich zwischendurch mir mit GetImageCount die Anzhal der Icons hole, zeigt er mir auch nur meine 100 Icons an. Also gehe ich davon aus, das das mit dem Remove geklappt hat.

    [ Dieser Beitrag wurde am 11.04.2003 um 09:43 Uhr von andreasvolgmann editiert. ]



  • Das mit Remove hat geklappt. Aber Icons sind GDI-Objekte im globalen Windows-Speicher, und Du hast davon unter Win98/ME nur MAX_SHORT zur Verfügung!
    Du musst also nach dem Remove aus der ImageList auch noch Gegenteil von CreateIcon ausführen, sozusagen DestroyIcon.



  • Und wie mache ich das? Habe keinen Befehl dafür in CImageList gefunden.
    Außerdem benutze ich gerade Win2000.

    [ Dieser Beitrag wurde am 11.04.2003 um 09:48 Uhr von andreasvolgmann editiert. ]



  • for (int i = m_ImageList.GetImageCount(); i >= 0; i--){
        m_ImageList.Remove(i);} // Komplette ImageList wieder löschen
    

    Calls the ImageList_Remove function to remove all of the images from an image list.

    BOOL ImageList_Remove(
    HIMAGELIST himl
    );



  • Nunja, ein bissel Denken beim Programmieren würde nicht schaden.

    1. Was sagt SHFILEINFO (MSDN) ??

    hIcon
    Handle to the icon that represents the file. You are responsible for destroying this handle with DestroyIcon when you no longer need it.

    2. Eine ImageListe speichert nur Handles. Sie weiss nicht, woher sie kommen, und ob sie diese Handles überhaupt löschen darf, wenn sie aus der Liste entfernt werden. Daher musst DU das erledigen.

    3. Leider weisst die ImageListe keine Funktion auf, ein in ihr gespeichertes Handle zurückzugeben.
    -> Wir müssen eine neue Liste erstellen, in der die Handles nochmal gespeichert werden, und die wir dann löschen können.

    CArray<HICON> m_IconArray;
    { für alle Icons
      m_ImageList.Add( shFileInfo.hIcon); 
      m_IconArray.Add( shFileInfo.hIcon);
    }
    
    // löschen
    m_ImageList.Remove( -1); // löscht alle Einträge
    for( int i=0; i<m_IconArray.GetCount(); i++)
      ::DestroyIcon( m_IconArray[i];
    m_IconArray.RemoveAll();
    


  • OK, danke.
    Aber bei mir steht in der MSDN (von CD installiert) nur
    hIcon
    Handle to the icon that represents the file.

    Daher wußte ich nicht, das ich das selber löschen muß. Aber danke nochmal. Werd es dann gleich mal ausprobieren.

    Aber was ist mit
    BOOL GetImageInfo( int nImage, IMAGEINFO* pImageInfo ) const;

    typedef struct _IMAGEINFO {
    HBITMAP hbmImage;
    HBITMAP hbmMask;
    int Unused1;
    int Unused2;
    RECT rcImage;
    } IMAGEINFO, FAR *LPIMAGEINFO;

    hbmImage
    Handle to the bitmap that contains the images.

    Kann ich denn nicht über die ImageInfo das Handle bekommen, dann kann ich mir doch das Array sparen?!

    Und außerdem kann ja nicht jeder so ein Profi sein. Wenn alle alles können würden, dann wäre dieses Forum ja sinnlos.



  • Wenn alle alles können würden, dann wäre dieses Forum ja sinnlos.

    Deswegen helfe ich ja trotzdem 😉

    Wenn das Icon in die ImageListe eingefügt wird, ruft die ImageList intern GetIconInfo auf und speichert daraus die Bitmaps, welche dann auch von der ImageListe verwaltet und beim Entfernen automatisch gelöscht werden.
    Aber, das IconHandle ist trotzdem noch vorhanden. Du bist für die Laufzeitexistenz verantwortlich.



  • Danke! Super!
    Jetzt klappt es! Jetzt zeigt er mir immer alle Icons an.



  • 0 problemo


Anmelden zum Antworten