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 :

CListCtrl - multiline


Sujet :

MFC

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 82
    Par défaut CListCtrl - multiline
    bonjour, je travail avec un CListCtrl, qui contient 3 colonnes
    1er colonne = une image de 75x75 pixel , dans la seconde colonnes, je veux mettres des informations sur plusieurs lignes.
    Je fais ,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    CString str;
    str.Format("DATE : %s \r\nLANGUE : %s",strDate,strLangue);
    ...
    ...
    lvItem.iSubItem	       = 1;			// Initialisation de la colonne "Col B"
    lvItem.mask		 = LVIF_TEXT;	// avec du texte seulement
    lvItem.pszText		= str(arData.GetAt(3).GetLength());
    lvItem.cchTextMax     = strlen(lvItem.pszText);
    j'ai le résultat (deux carrés blanc a la place de \r\n) :
    DATE : 10/03/2006 LANGUE : FR

    au lieu d'obtenir
    DATE : 10/03/2006
    LANGUE : FR

  2. #2
    tut
    tut est déconnecté
    Membre éclairé
    Avatar de tut
    Inscrit en
    Juillet 2002
    Messages
    373
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 373
    Par défaut
    ...parce que CListCtrl ne gère pas les "\r" et "\n", il doit les voir comme des caractères non-imprimables.
    Donc, tu peux soit essayer de trouver un composant sur internet qui ferait ça (voir le site codeproject.com et/ou codeguru.com, par exemple), soit créer ton propre composant (en utilisant le mode OwnerDraw...good luck!)...

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 82
    Par défaut
    j'ai trouvé ceci, qui résoud une partie de mon probleme.
    j'obtiens bien plusieurs ligne pour une colonne,
    mais si je veux positionner une image en 1er position. l'image ne s'afffiche pas
    il ne tiens compte que du texte et non pas dutout des images.
    Quelqu'un pourrai m'aider a modifier ce code pour pouvoir intégrer des images dans la 1er colonne, merci.
    CListCtrlEx.CPP
    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
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
     
    void CListCtrlEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
    {
    	TCHAR  lpBuffer[256];
     
    	LV_ITEM lvi;
     
    	lvi.mask = LVIF_TEXT | LVIF_PARAM ;
    	lvi.iItem = lpDrawItemStruct->itemID ; 	
    	lvi.iSubItem = 0;
    	lvi.pszText = lpBuffer ;
    	lvi.cchTextMax = sizeof(lpBuffer);
    	VERIFY(GetItem(&lvi));
     
    	LV_COLUMN lvc, lvcprev ;
    	::ZeroMemory(&lvc, sizeof(lvc));
    	::ZeroMemory(&lvcprev, sizeof(lvcprev));
    	lvc.mask = LVCF_WIDTH | LVCF_FMT;
    	lvcprev.mask = LVCF_WIDTH | LVCF_FMT;
     
    	for ( int nCol=0; GetColumn(nCol, &lvc); nCol++)
    	{
    		if ( nCol > 0 ) 
    		{
    			// Get Previous Column Width in order to move the next display item
    			GetColumn(nCol-1, &lvcprev) ;
    			lpDrawItemStruct->rcItem.left += lvcprev.cx ;
    			lpDrawItemStruct->rcItem.right += lpDrawItemStruct->rcItem.left ;	
    		}
     
    		// Get the text 
    		::ZeroMemory(&lvi, sizeof(lvi));
    		lvi.iItem = lpDrawItemStruct->itemID;
    		lvi.mask = LVIF_TEXT | LVIF_PARAM;
    		lvi.iSubItem = nCol;
    		lvi.pszText = lpBuffer;
    		lvi.cchTextMax = sizeof(lpBuffer);
    		VERIFY(GetItem(&lvi));
     
    		CDC* pDC;
    		pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
     
    		if ( lpDrawItemStruct->itemState & ODS_SELECTED )
    		{
    			pDC->FillSolidRect(&lpDrawItemStruct->rcItem, GetSysColor(COLOR_HIGHLIGHT)) ; 
    			pDC->SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT)) ;
    		}
    		else
    		{
    			pDC->FillSolidRect(&lpDrawItemStruct->rcItem, GetSysColor(COLOR_WINDOW)) ;
    		    pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT)) ; 
    		}
     
    		pDC->SelectObject(GetStockObject(DEFAULT_GUI_FONT));
     
    		UINT		uFormat    = DT_LEFT ;
     
    		::DrawText(lpDrawItemStruct->hDC, lpBuffer, strlen(lpBuffer), 
    			 &lpDrawItemStruct->rcItem,uFormat) ;
     
    		pDC->SelectStockObject(SYSTEM_FONT) ;
    	}
    }
     
    LRESULT CListCtrlEx::OnSetFont(WPARAM wParam, LPARAM lParam)
    {
    	CRect rc;
    	GetWindowRect(&rc);
     
    	WINDOWPOS wp;
    	wp.hwnd = this->m_hWnd;
    	wp.cx = rc.Width() ;
    	wp.cy = rc.Height() ;
    	wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;
     
    	LRESULT lrReturn(Default());
     
    	SendMessage(WM_WINDOWPOSCHANGED, 0, reinterpret_cast<LPARAM> (&wp));
     
    	return lrReturn;
    }
     
    void CListCtrlEx::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) 
    {
    	// Get the LOGFONT for the current font.
    	LOGFONT lf;
    	::ZeroMemory(&lf, sizeof(lf));
     
    	CFont* pFont = GetFont();
    	ASSERT_VALID(pFont);
     
    	if (pFont) 
    		VERIFY(pFont->GetLogFont(&lf));
     
    	int nAdj(4) ;
    	m_nLinesPerRow = max(m_nLinesPerRow, 1);
     
    	if (lf.lfHeight < 0) 
    		lpMeasureItemStruct->itemHeight = ((-lf.lfHeight+nAdj) * (m_nLinesPerRow));
    	else 
    		lpMeasureItemStruct->itemHeight = ((lf.lfHeight+nAdj) * (m_nLinesPerRow));
    }
     
     
    void CListCtrlEx::OnInitialUpdate() 
    {
    	int i, j ;
     
    	LV_COLUMN lvc;
    	lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
     
    	// Insert Header columns
    	for(i = 0; i<m_nColumns; i++)
    	{
    		lvc.iSubItem = i;
    		lvc.pszText = _gszColumnLabel[i];
    		lvc.cx = _gnColumnWidth[i];
    		lvc.fmt = _gnColumnFmt[i];
    		InsertColumn(i,&lvc);
    	}
     
    	// Insert First Column items for every row
    	LV_ITEM lvi;
    	lvi.mask = LVIF_TEXT | LVIF_STATE ;
     
    	char	buf[51] ;
    	for(i=0; i<m_nRows; i++)
    	{
    		sprintf(buf, "Line 1 text \n lots a a \n more text") ;
    		lvi.iItem = i;
    		lvi.iSubItem = 0;
    		lvi.state = LVIS_SELECTED | LVIS_FOCUSED ;
    		lvi.stateMask = LVIS_SELECTED | LVIS_FOCUSED ;
    		lvi.pszText = buf ;
    		InsertItem(&lvi);
     
            if (i == 0) m_nLinesPerRow = 3;
    		else m_nLinesPerRow = 5;
     
    		for(j = 1; j<m_nColumns; j++)
    		{
    			SetItemText(i,j,_gszItem[i][j]);
    		}
    	}
     
    //	if ( m_nLinesPerRow > 1 ) 
    //	{
    		m_NewListFont.CreatePointFont(180,"MS Serif");
    		SetFont(&m_NewListFont);
    //	}
     
    	CHeaderCtrl* pHeader = NULL;
    	pHeader=GetHeaderCtrl();
     
    	if(pHeader==NULL)
    		return;
     
    	VERIFY(m_HeaderCtrl.SubclassWindow(pHeader->m_hWnd));	
     
    	HDITEM hdItem;
     
    	hdItem.mask = HDI_FORMAT;
     
    	for(i=0; i<m_HeaderCtrl.GetItemCount(); i++)
    	{
    		m_HeaderCtrl.GetItem(i,&hdItem);
     
    		hdItem.fmt|= HDF_OWNERDRAW;
     
    		m_HeaderCtrl.SetItem(i,&hdItem);
    	}
    }
     
    void CListCtrlEx::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct) 
    {
     
    	CListCtrl::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
    }
    CListCtrlEx.H
    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
     
    static _TCHAR *_gszColumnLabel[4] =
    {
    	_T("Color\nName"), _T("Red\nColor"), _T("Blue\nColor"), _T("Black\nColor")
    };
     
     
    static int _gnColumnWidth[4] =
    {
    	150, 100, 150, 80
    };
     
     
    static int _gnColumnFmt[4] =
    {
    	LVCFMT_LEFT, LVCFMT_RIGHT, LVCFMT_RIGHT
    };
     
     
    static _TCHAR *_gszItem[2][4] =
    {
    	_T("Yellow\nY"),  _T("255\n255"), _T("30"), _T("50"),
    	_T("Red\nR"),     _T("255"), _T("30"), _T("50") 
    };
     
    class CListCtrlEx : public CListCtrl
    {
    // Construction
    public:
    	CListCtrlEx();
     
    // Attributes
    public:
    	int		m_nLinesPerRow;	
    	int     m_nColumns, m_nRows ;
     
    	CFont			m_NewListFont;
    	CHeaderCtrlEx	m_HeaderCtrl ;
     
    	void OnInitialUpdate() ;
    	void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) ;
     
    	void SetNoOfLinesPerRow(int n)  { m_nLinesPerRow = n ; }
    	void SetNoOfColumns(int n=1)	{ m_nColumns = n ; }
    	void SetNoOfRows(int n=0)		{ m_nRows = n ; }
     
    	afx_msg LRESULT	OnSetFont(WPARAM wParam, LPARAM lParam);
    	afx_msg void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
     
    // Operations
    public:
     
    // Overrides
    	// ClassWizard generated virtual function overrides
    	//{{AFX_VIRTUAL(CListCtrlEx)
    	//}}AFX_VIRTUAL
     
    // Implementation
    public:
    	virtual ~CListCtrlEx();
     
    	// Generated message map functions
    protected:
    	//{{AFX_MSG(CListCtrlEx)
    	afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct);
    	//}}AFX_MSG
     
    	DECLARE_MESSAGE_MAP()
    };

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 171
    Par défaut
    J'ai à peu près le même problème que psykotik : je voudrais faire du multiline dans un clistctrl (plus précisément un clistview dans mon cas).
    J'ai deux soucis :
    - je ne trouve pas la méthode MeasureItem à implémenter (bien que je trouve le message OnMeasureItem, que j'ai implémenté mais il n'y passe pas!!)
    - je voudrais que le nombre de lignes d'un item s'adapte au texte. Y a-t-il un moyen de connaître, selon la font, la largeur graphique totale d'un cstring? (afin de le diviser en plusieurs lignes).

    Grosso-modo : multiligne et coupure automatique dans un clistview.

  5. #5
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    salut,
    il faut que ta CListView soit owner draw alors measureitem sera appelée .
    voir faq pour le dessin des lignes :
    http://c.developpez.com/faq/vc/?page...tCtrlOwnerDraw

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 171
    Par défaut
    Elle devrait y être puisque je l'ai spécifié dans precreatewindow
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    BOOL CScriptView::CreCreateWindow(CREATESTRUCT& cs)
    {
        cs.style |=  LVS_OWNERDRAWFIXED;
        return CListView::CreCreateWindow(cs);
    }
    Y aurait-il une erreur?

    Autre question : measureItem sera-t-il appelé avant chaque drawitem? quand est-il appelé en fait?

  7. #7
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    bon apres verifications ,il n'y a pas de measureitem sur la clistctrl.
    tu ne pourras pas avoir des lignes de hauteur différentes.
    eventuellement tu peux afficher la zone en multi-ligne dans le tooltip...

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 171
    Par défaut
    Merci pour ces renseignements farscape.

    En fait je viens de découvrir que le message traité par le classe wizard (WM_MEASUREITEM) n'était pas le bon, il faut s'occuper du message qui est traité par ON_WM_MEASUREITEM_REFLECT() qui lui n'est pas géré par le class wizard.

    Je l'ai donc ajouté à la main, il marche bien, sauf qu'il est appelé qu'une seule fois : lors de l'initdialog de ma clistview. Pourtant, moi j'ai besoin qu'il soit appelé plus souvent car le contenu de ma liste change et donc il faut recalculer le nombre de lignes de chaque entrée de la liste à chaque modification!

    Y a-t-il une solution ou dois-je abandonner maintenant? Ne peut-on pas lancer le message correspondant au ON_WM_MEASUREITEM_REFLECT() manuellement?

    Merci encore pour votre aide à tous

  9. #9
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    il doit être appelé une seule fois pour préciser la hauteur de toutes les lignes.
    je n'ai pas trouvé de message spécifique permettant de spécifier le rectangle d'affichage d'une item..

    d'ailleurs si on fait le parallèle avec la CListBox il n'y a pas d'option Ownerdraw variable permettant justement de gérer la hauteur de chaque ligne...

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 171
    Par défaut
    Donc tu confirmes : impossible de faire du multiligne DYNAMIQUE dans une cListView?
    Quelqu'un voit une solution alternative, un autre type de composant qui conviendrait?

    (Farscape : des réponses rapides, justes et claires. Bravo! Pour ta doc mfc aussi, qui est vraiment bonne.)

  11. #11
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    oui,
    j'ai utilisé ce composant sur codeproject qui est pas mal :
    http://www.codeproject.com/miscctrl/reportctrl.asp

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

Discussions similaires

  1. [MFC] CListCtrl: colonnes fixes + tri des items
    Par bigboomshakala dans le forum MFC
    Réponses: 5
    Dernier message: 10/05/2004, 22h54
  2. Selectionner ligne dans une ClistCtrl
    Par fr66 dans le forum MFC
    Réponses: 2
    Dernier message: 03/05/2004, 14h58
  3. Réponses: 4
    Dernier message: 25/02/2004, 08h22
  4. Réponses: 3
    Dernier message: 18/11/2003, 13h22
  5. [MFC] image dans un header de CListCtrl
    Par tut dans le forum MFC
    Réponses: 3
    Dernier message: 11/06/2003, 15h26

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