IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MFC Discussion :

[MFC] Disparition des images dans une CListCtrl


Sujet :

MFC

  1. #1
    Candidat au Club
    Inscrit en
    Mai 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 9
    Points : 2
    Points
    2
    Par défaut [MFC] Disparition des images dans une CListCtrl
    Bonjour,

    Je réalise actuellement un petit soft basé sur une SDI. Depuis cette SDI, je fais ouvrir une boite de Dialogue "CFileTransferDlg" dans la quelle j'ai recréé manuellement un explorer type windows (arbre CTreeCtrl à gauche et liste CListCtrl à droite). L'arbre est pleinement fonctionnel : affichage des dossiers et fichiers dans l'arborescence...etc. Il n'y a juste qu'un seul problème qui se situe au niveau des images de la liste.

    Depuis ma SDI, lorsque j'ouvre ma boite de Dialogue (en cliquant sur une icone d'une barre d'outils) la première fois, tout marche parfaitement, et les icones de l'arbre et de la liste s'affichent correctement. Si je ferme ma boite de Dialogue et que je la réouvre juste après, les textes de mon arbre et de ma liste s'affichent mais je n'ai plus les icones.


    Je décris ici comment j'ai procédé dans mon code, pour la construction des listes d'images associées à l'arbre et à la liste.

    Pour la boite de Dialogue :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
     
    class CFileTransferDlg : public CDialog
    {
    public:
    	CFileTransferDlg(CWnd* pParent = NULL);   // standard constructor
    	~CFileTransferDlg();
     
    	CPcTreeCtrl	m_PcTreeCtrl;	
    	CPcListCtrl	m_PcListCtrl;
     
    protected:
    	CImageList	*m_pPcTreeCtrlImageList;
    	CImageList	*m_pPcListCtrlImageList;
    };
     
    CFileTransferDlg::CFileTransferDlg(CWnd* pParent /*=NULL*/)
    	: CDialog(CFileTransferDlg::IDD, pParent)
    {
    	//{{AFX_DATA_INIT(CFileTransferDlg)
    	//}}AFX_DATA_INIT
    	m_pPcTreeCtrlImageList = NULL;
    	m_pPcListCtrlImageList = NULL;
    }
     
    BOOL CFileTransferDlg::OnInitDialog() 
    {
    	CDialog::OnInitDialog();
     
    	(...)
     
    	CString strPcPath= "D:\\Test\\";
     
    	//----------------------------------------
    	// Creates an ImageList
    	//----------------------------------------
     
    	SHFILEINFO sfi;
    	HIMAGELIST hSystemImageList = (HIMAGELIST) SHGetFileInfo(_T("C:\\"), 0, &sfi, sizeof(SHFILEINFO),
    															 SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
     
    	m_pPcTreeCtrlImageList = new CImageList();
    	m_pPcListCtrlImageList = new CImageList();
     
    	ASSERT(m_pPcTreeCtrlImageList != NULL && m_pPcListCtrlImageList != NULL);    // serious allocation failure checking
     
    	VERIFY(m_pPcTreeCtrlImageList->Attach(hSystemImageList));
    	m_PcTreeCtrl.SetImageList(m_pPcTreeCtrlImageList, TVSIL_NORMAL);
    	m_pPcTreeCtrlImageList->Detach();
     
    	VERIFY(m_pPcListCtrlImageList->Attach(hSystemImageList));
    	m_PcListCtrl.SetImageList(m_pPcListCtrlImageList, LVSIL_SMALL);
     
    	(...)
     
    	//---------------------------------------------
    	//Display the folder items in the Pc Tree
    	//---------------------------------------------
    	m_PcTreeCtrl.DisplayDrives(TVI_ROOT, FALSE);
    	m_PcTreeCtrl.SetSelectedPath(strPcPath, 1);
     
    	//----------------------------------------
    	// Add columns to the list ctrl.
    	//----------------------------------------
    	m_PcListCtrl.InsertColumn (0, _T ("Nom"), LVCFMT_LEFT, 170);
    	m_PcListCtrl.InsertColumn (1, _T ("Taille"), LVCFMT_RIGHT, 70);
    	m_PcListCtrl.InsertColumn (2, _T ("Modifié le"), LVCFMT_LEFT, 100);
     
    	//---------------------------------------------
    	// Initialize  m_pPcListCtrl & m_pPcTreeCtrl
    	//---------------------------------------------
    	m_PcTreeCtrl.m_pPcListCtrl = &m_PcListCtrl;
    	m_PcListCtrl.m_pPcTreeCtrl = &m_PcTreeCtrl;
     
    	//----------------------------------------
    	// Populate the list ctrl with items.
    	//----------------------------------------
    	m_PcListCtrl.DisplayPath (strPcPath);
    }
    Dans le CTreeCtrl :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void CPcTreeCtrl::OnDestroy() 
    {
    	CTreeCtrl::OnDestroy();
     
    	CImageList  *pimagelist;
    	pimagelist = GetImageList(TVSIL_NORMAL);
    	delete pimagelist;	
    }
    Dans le CListCtrl :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void CPcListCtrl::OnDestroy() 
    {
    	CListCtrl::OnDestroy();
     
    	CImageList  *pimagelist;
    	pimagelist = GetImageList(LVSIL_SMALL);
    	delete pimagelist;	
    }

    A noter aussi que si je mets en commentaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	VERIFY(m_pPcListCtrlImageList->Attach(hSystemImageList));
    	m_PcListCtrl.SetImageList(m_pPcListCtrlImageList, LVSIL_SMALL);
    alors lorsque je ferme et réouvre autant de fois que je veux ma boite de Dialogue, les images s'affichent correctement dans l'arbre.

    J'en déduis que c'est la liste qui me fout un peu le bordel dans l'affichage des images.

    Quelqu'un aurait-il une idée pour résoudre mon problème ? Merci par avance.

  2. #2
    Candidat au Club
    Inscrit en
    Mai 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    Je me permets de remonter mon sujet en espérant que quelqu'un puisse m'aider.

    Je peux donner d'autres renseignements sur mon problème ou même fournir mes fichiers sources si besoin.

  3. #3
    Membre habitué
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Points : 138
    Points
    138
    Par défaut
    Salut,
    Je ne sais pas trop pour ton problème mais pourquoi fais-tu un Detach sur ton imageList ? Je ne pense pas que le tree fasse une copie du handle de l'imageListe que tu lui passe, ça me parait bizarre.

  4. #4
    Candidat au Club
    Inscrit en
    Mai 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Brouzouf
    Salut,
    Je ne sais pas trop pour ton problème mais pourquoi fais-tu un Detach sur ton imageList ? Je ne pense pas que le tree fasse une copie du handle de l'imageListe que tu lui passe, ça me parait bizarre.
    Je ne sais pas exactement à quoi sert le Detach() mais si je ne le fais pas, je ne peux pas attacher d'ImageList à la liste "m_pPcListCtrlImageList".

  5. #5
    Membre habitué
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Points : 138
    Points
    138
    Par défaut
    Il me parait normal que tu ne puisse pas attacher deux fois une même imageliste, par contre tu peux la récupérer deux fois en faisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    HIMAGELIST hSystemImageList1 = (HIMAGELIST) SHGetFileInfo(_T("C:\\"), 0, &sfi, sizeof(SHFILEINFO),
    HIMAGELIST hSystemImageList2 = (HIMAGELIST) SHGetFileInfo(_T("C:\\"), 0, &sfi, sizeof(SHFILEINFO),
    Puis tu les utilises toutes les deux sans faire de detach car a mon avis c'est ça qui doit te poser problème.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    VERIFY(m_pPcTreeCtrlImageList->Attach(hSystemImageList1));
    	m_PcTreeCtrl.SetImageList(m_pPcTreeCtrlImageList, TVSIL_NORMAL);
     
    	VERIFY(m_pPcListCtrlImageList->Attach(hSystemImageList2));
    	m_PcListCtrl.SetImageList(m_pPcListCtrlImageList, LVSIL_SMALL);
    Essaye et dis-nous le résultat.

  6. #6
    Candidat au Club
    Inscrit en
    Mai 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Brouzouf
    Essaye et dis-nous le résultat.
    J'ai testé et j'ai un joli "Debug Assertion Failed"... qui provient du deuxième "Attach()".

  7. #7
    Membre habitué
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Points : 138
    Points
    138
    Par défaut
    Tes deux HIMAGELIST ont-ils la meme valeur ?

  8. #8
    Candidat au Club
    Inscrit en
    Mai 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Brouzouf
    Tes deux HIMAGELIST ont-ils la meme valeur ?
    Oui ils ont la même valeur. Sincèrement je ne pense pas que le problème vienne du "Detach()".

  9. #9
    Membre habitué
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Points : 138
    Points
    138
    Par défaut
    Je pense que si, mais de toute façon je crois que tu ne peux pas attacher deux fois le même handle d'imagelist à deux imagelist différentes, c'est pour ça que tu as ton detach.

    Mais par contre, tu peux récupérer le handle de l'icon représentant c: comme tu le fait actuellement, il faut juste que tu changes un flag, et ce handle tu peux l'ajouter à une CImageList que tu dois créer dynamiquement.

    Je pense que tu dois récupérer le handle de l'icone.
    Puis tu crée deux imagelistes.
    Puis tu ajoute cet icone à tes imagelistes.

    J'espère que ça fonctionnera, c'est comme ça que j'essaierai de faire.

    Que contient ton imagelist normalement ?

  10. #10
    Candidat au Club
    Inscrit en
    Mai 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Brouzouf
    Je pense que si, mais de toute façon je crois que tu ne peux pas attacher deux fois le même handle d'imagelist à deux imagelist différentes, c'est pour ça que tu as ton detach.

    Mais par contre, tu peux récupérer le handle de l'icon représentant c: comme tu le fait actuellement, il faut juste que tu changes un flag, et ce handle tu peux l'ajouter à une CImageList que tu dois créer dynamiquement.

    Je pense que tu dois récupérer le handle de l'icone.
    Puis tu crée deux imagelistes.
    Puis tu ajoute cet icone à tes imagelistes.

    J'espère que ça fonctionnera, c'est comme ça que j'essaierai de faire.

    Que contient ton imagelist normalement ?
    Désolé mais c'est de l'hébreu pour moi ce que tu racontes. Je n'ai que des connaissances limitées dans le domaine.

    Mon ImageList contient la liste de toutes les images du système (images des lecteurs de disques, de disquettes, des fichiers ...etc...). On associe ensuite ces listes d'images à un arbre (CTreeCtrl) ou une liste (CListCtrl) et lorsqu'on affiche un item de l'arbre ou de la liste, on y indique le numéro de l'image de la liste que l'on souhaite.

    En gros ce que j'ai fait marche parfaitement : j'ouvre ma boite de dialogue et je vois bien mon arbre et ma liste avec les bonnes images associées. C'est uniquement lorsque je ferme ma boite de Dialogue et que je la réouvre que je n'ai plus mes images.

  11. #11
    Membre habitué
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Points : 138
    Points
    138
    Par défaut
    Est-ce que tu peux envoyer ton code, faisant ce que tu dis pour que je puisse tester ça par moi même (pas le temps de tout écrire) ?

  12. #12
    Candidat au Club
    Inscrit en
    Mai 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Brouzouf
    Est-ce que tu peux envoyer ton code, faisant ce que tu dis pour que je puisse tester ça par moi même (pas le temps de tout écrire) ?
    Oui bien sûr.

    J'ai mis une archive zip en fichier joint comportant le Worspace "allégé" de mon application.

    Pour voir le bug, il faut lancer l'application, puis cliquer sur la petite icone centrale ("AWG File Transfer & Control"). On voit alors la boite de Dialogue de type Explorer Windows. Si on referme juste la boite de Dialogue et qu'on la ré-ouvre dans la foulée, alors les images n'apparaissent plus dans l'arbre et la liste.

    Edit : Voir le fichier joint un peu plus bas.

  13. #13
    Membre habitué
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Points : 138
    Points
    138
    Par défaut
    Ok je regarde ça ce soir car la je suis au boulot et on en reparle demain.

  14. #14
    Candidat au Club
    Inscrit en
    Mai 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Bon finalement ce matin j'ai plus ou moins réussi à corriger le problème. La seule modification se situe au niveau du CListCtrl où j'ai remplacé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void CPcListCtrl::OnDestroy() 
    {
    	CListCtrl::OnDestroy();
     
    	CImageList  *pimagelist;
    	pimagelist = GetImageList(LVSIL_SMALL);
    	delete pimagelist;	
    }
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void CPcListCtrl::OnDestroy() 
    {
    	CListCtrl::OnDestroy();
     
    	CImageList  *pimagelist;
    	pimagelist = GetImageList(LVSIL_SMALL);
    	pimagelist->Detach();	
    }
    Par contre avec cette solution je ne supprime jamais le pointeur sur la liste d'images...

  15. #15
    Membre habitué
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Points : 138
    Points
    138
    Par défaut
    Oui c'est ce que je viens de trouver car en fait tu détruisais la liste systeme .
    Par contre lors de l'initialisation de tes listes, en fait tu n'en a besoin que de une que tu affectes au treeview et au liste controle et tu n'as pas besoin de faire de Detach().
    Il faut absolument que tu fasses un Detach() sur ton ImageList avant de la detruire sinon tu detruira la liste système.

  16. #16
    Candidat au Club
    Inscrit en
    Mai 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    Je reviens ici poster la solution à mon problème, qui pourrait aider quelqu'un ayant le même problème que moi.

    J'ai sensiblement amélioré le code de mon "explorer" et voici ce que j'ai fait :

    Dans ma boîte de Dialogue :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    class CFileTransferDlg : public CDialog
    {
    public:
    	CFileTransferDlg(CWnd* pParent = NULL);   // standard constructor
    	~CFileTransferDlg();
     
    	CPcTreeCtrl	m_PcTreeCtrl;	
    	CPcListCtrl	m_PcListCtrl;
     
    protected:
    	CImageList	*m_pSystImageList;
    };
     
    //-------------------------------------
     
    CFileTransferDlg::CFileTransferDlg(CWnd* pParent /*=NULL*/)
    	: CDialog(CFileTransferDlg::IDD, pParent)
    {
    	//{{AFX_DATA_INIT(CFileTransferDlg)
    	//}}AFX_DATA_INIT
    	m_pSystImageList = NULL;
    }
     
    //-------------------------------------
     
    CFileTransferDlg::~CFileTransferDlg()
    {
    	delete m_pSystImageList;
    }
     
    BOOL CFileTransferDlg::OnInitDialog() 
    {
    	CDialog::OnInitDialog();
     
    	//----------------------------------------
    	// Creates an ImageList
    	//----------------------------------------
    	CUseShGetFileInfo FileInfo;
     
    	m_pSystImageList = new CImageList();
     
    	ASSERT(m_pSystImageList != NULL);    // serious allocation failure checking
    	VERIFY(m_pSystImageList->Attach(FileInfo.GetSystemImageListHandle(TRUE)));
     
    	m_PcTreeCtrl.SetImageList(m_pSystImageList, TVSIL_NORMAL);
    	m_PcListCtrl.SetImageList(m_pSystImageList, LVSIL_SMALL);
     
    	(...)
    }
    Dans le TreeCtrl :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void CPcTreeCtrl::OnDestroy() 
    {
    	CTreeCtrl::OnDestroy();
     
    	CImageList  *pimagelist;
     
    	pimagelist = GetImageList(TVSIL_NORMAL);
     
    	delete pimagelist;	
    }
    Dans le ListCtrl :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void CPcListCtrl::OnDestroy() 
    {
    	CListCtrl::OnDestroy();
     
    	CImageList  *pimagelist;
     
    	pimagelist = GetImageList(LVSIL_SMALL);
     
    	pimagelist->Detach();
    }
    Important : il faut absolument que la ListCtrl ait la propriété LVS_SHAREIMAGELISTS

    Je rajoute en pièce jointe le code complet de cette mini-application.
    Fichiers attachés Fichiers attachés

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment stocker des images dans une base de données ?
    Par [Silk] dans le forum Bases de données
    Réponses: 4
    Dernier message: 21/07/2005, 12h29
  2. [MFC] surbrillance de ligne dans une CListCtrl
    Par Yoshette dans le forum MFC
    Réponses: 4
    Dernier message: 15/04/2005, 17h09
  3. inserer des images dans une base de données
    Par alilou04 dans le forum Bases de données
    Réponses: 2
    Dernier message: 28/06/2004, 19h54
  4. LYCOS ET MYSQL - Intégrer des images dans une base!
    Par archeo dans le forum Installation
    Réponses: 3
    Dernier message: 06/04/2004, 14h45
  5. insérer des images dans une bd postgresql
    Par ephet dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 20/01/2004, 10h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo