bonjour
quelqu'un saurait-il comment on pourrait colorer un item unique d'un treectrl ?
merci d'avance
SBP
bonjour
quelqu'un saurait-il comment on pourrait colorer un item unique d'un treectrl ?
merci d'avance
SBP
salut,
il y a rien en standard il faut ruser ,
il creer une classe derivée d'un CTreeCtrl et reprendre la main sur le paint
il faut juste rajouter un test au milieu pour determiner quel item tu dois traiter ou non.
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 //--------------------------------------------------------------- void CDirTreeCtrl::OnPaint() { // TODO: Add your message handler code here // Do not call CTreeCtrl::OnPaint() for painting messages CPaintDC dc(this); CDC memDC; memDC.CreateCompatibleDC( &dc ); CRect rcClip, rcClient; dc.GetClipBox( &rcClip ); GetClientRect(&rcClient); CBitmap bitmap; bitmap.CreateCompatibleBitmap( &dc, rcClient.Width(), rcClient.Height() ); memDC.SelectObject( &bitmap ); CRgn rgn; rgn.CreateRectRgnIndirect( &rcClip ); memDC.SelectClipRgn(&rgn); rgn.DeleteObject(); // laisser le controle se dessiner CWnd::DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 ); HTREEITEM hItem = GetFirstVisibleItem(); int n = GetVisibleCount()+1; while( hItem && n--) { CRect rect; CString str= GetItemText( hItem ); GetItemRect( hItem, &rect, TRUE ); memDC.SetTextColor(RGB(0xFF, 0xFF, 0xE0) ); memDC.TextOut( rect.left+2, rect.top+1, sItem ); hItem = GetNextVisibleItem( hItem ); } dc.BitBlt( rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), &memDC, rcClip.left, rcClip.top, SRCCOPY ); }
j'ai une erreur sur la compile de ton code
sur cette ligne , c'est qui sItem ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 memDC.TextOut( rect.left+2, rect.top+1, sItem );
SBP
bon oublié la question précédente j'ai trouvé mais j'ai quand meme un autre probleme , j'ai fais un petit projet rapide avec une classe derivé de CTreeCtrl pour teste ce code et voila je passe jamais dans la fonction Paint surcharger , quelqu'un saurait-il pourquoi ?
voila comment je crée mes item
merci d'avance
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 HTREEITEM test; HTREEITEM racine = m_Tree.InsertItem(&RootTreeView); test = m_Tree.InsertItem(TVIF_TEXT| TVIF_IMAGE | TVIF_SELECTEDIMAGE,"test",0,0,0,0,0,racine,TVI_ROOT); test = m_Tree.InsertItem(TVIF_TEXT| TVIF_IMAGE | TVIF_SELECTEDIMAGE,"test 2",0,0,0,0,0,racine,TVI_ROOT);
salut,
tu as bien l:
ON_WM_PAINT()
dans ton BEGIN_MESSAGE_MAP ?
sitem c'etait une erreur de copier coller c'est str bien sur .
oui je l'ai dans la DLG qui me sert de base , d'ailleur il me semble que le code ne passe que par le paint de la DLG et non par le paint du tree , voila le réel probléme
re,
le paint est a redefinir dans la classe derivée du ctreectrl pas dans la dialogue .
c'est bien ce que j'ai fais , néamoins le WM_ONPAINT de ma fenetre pointe sur un Onpaint de la DLG et apparament c'est uniquement celui la qui est executé
SBP
bon on reprend :
exemple pour ma classe CDirTreeCtrl:
tu as bien cette config au niveau du treeCtrl.?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 BEGIN_MESSAGE_MAP(CDirTreeCtrl, CTreeCtrl) //{{AFX_MSG_MAP(CDirTreeCtrl) ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemexpanded) ON_WM_LBUTTONDOWN() ON_WM_KEYDOWN() ON_WM_PAINT() //}}AFX_MSG_MAP END_MESSAGE_MAP() //--------------------------------------------------------------- void CDirTreeCtrl::OnPaint() { ....
met entre commentaire l'appel du paint (message et fonction) au niveau de la dialog .
merci , c'est bon j'ai trouvé . je suis vraiement nul j'avais pas déclarer correctement le paint dans le TreeCtrl , ca marche maintenant merci
SBP
Il reste toutefois un petit probleme , avec ce code ( voir message ci-dessus ) on ne voit plus la selection d'un item . Je m'explique avec l'objet simple lorsqu'un item est selectionné sont background change de couleur et permet ainsi de le différentié mais ici on ne voit plus rien a part un petit morceaux de cadre sur la gauche .
Quelqu'un a une idée ?
SBP
oui tu peux filtrer sur les items en selection :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 UINT selflag = TVIS_DROPHILITED | TVIS_SELECTED; if ( !(GetItemState( hItem, selflag ) & selflag ) { // le traitement . }
j'ai du mal m'expliquer , ton code me permet de filter le changement de couleur du texte hors c'est pas ca mon probleme.
Lorque je selectionne un item dans un Tree classique , le texte de l'item se retrouve dans un cadre de couleur foncé ce qui ne marche plus avec ta modif , hors moi je voudrais bien conservé ce cadrage coloré.
SBP
bon je recommence :
la modif precedente permet de filter l'item en selection .
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 //--------------------------------------------------------------- void CDirTreeCtrl::OnPaint() { // TODO: Add your message handler code here // Do not call CTreeCtrl::OnPaint() for painting messages CPaintDC dc(this); CDC memDC; memDC.CreateCompatibleDC( &dc ); CRect rcClip, rcClient; dc.GetClipBox( &rcClip ); GetClientRect(&rcClient); CBitmap bitmap; bitmap.CreateCompatibleBitmap( &dc, rcClient.Width(), rcClient.Height() ); memDC.SelectObject( &bitmap ); CRgn rgn; rgn.CreateRectRgnIndirect( &rcClip ); memDC.SelectClipRgn(&rgn); rgn.DeleteObject(); // laisser le controle se dessiner CWnd::DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 ); HTREEITEM hItem = GetFirstVisibleItem(); UINT selflag = TVIS_DROPHILITED | TVIS_SELECTED; int n = GetVisibleCount()+1; while( hItem && n--) { // changement de couleur uniquement si pas selectionné . if ( !(GetItemState( hItem, selflag ) & selflag ) { CRect rect; CString str= GetItemText( hItem ); GetItemRect( hItem, &rect, TRUE ); memDC.SetTextColor(RGB(0xFF, 0xFF, 0xE0) ); memDC.TextOut( rect.left+2, rect.top+1, sItem ); hItem = GetNextVisibleItem( hItem ); } } dc.BitBlt( rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), &memDC, rcClip.left, rcClip.top, SRCCOPY ); }
c'est mieux ?
j'ai l'impréssion de joué une scene de la cité de la peur la , toi tu parle de caravane et moi de berger allemand.
bon je reprend , ton code marche trés bien mais ce qu'il fait n'est pas ce que je cherche a faire .
Je voudrais ( comme avec un treectrl classique ) que quand je clique sur un element celui-ci apparaisse sur fond coloré comme lorsqu'on selectionne du texte dans ce message
SBP
re,
correction du code :
les items apparaissent (pour mon exemple ) en rouge
si on click sur un item la couleur de fond de base et d'ecriture reste inchangée (couleur d'origine blanc sur fond bleu)
si tu veux changer ça aussi il faut le traiter . (ce qui n'est pas tres dur) .
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 UINT selflag = TVIS_DROPHILITED | TVIS_SELECTED; int n = GetVisibleCount()+1; while( hItem && n--) { // changement de couleur uniquement si pas selectionné . if ( !(GetItemState( hItem, selflag ) & selflag )) { CRect rect; CString str= GetItemText( hItem ); GetItemRect( hItem, &rect, TRUE ); memDC.SetTextColor(RGB(255, 0, 0)); memDC.TextOut( rect.left+2, rect.top+1, str ); } hItem = GetNextVisibleItem( hItem ); }
code final:
cette version gere la couleur d'affichage de l'item ,
ecrit le texte avec la fonte du controle.
met un autre couleur de fond et d'ecriture quand l'item est en selection.
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 //--------------------------------------------------------------- void CDirTreeCtrl::OnPaint() { // TODO: Add your message handler code here // Do not call CTreeCtrl::OnPaint() for painting messages CPaintDC dc(this); // creation d'un DC en memoire . CDC memDC; memDC.CreateCompatibleDC( &dc ); CRect rcClip, rcClient; dc.GetClipBox( &rcClip ); GetClientRect(&rcClient); // seletionne un bitmap sur le DC en memoire CBitmap bitmap; bitmap.CreateCompatibleBitmap( &dc, rcClient.Width(), rcClient.Height() ); memDC.SelectObject( &bitmap ); // selectionne la region dans le dc en memoire CRgn rgn; rgn.CreateRectRgnIndirect( &rcClip ); memDC.SelectClipRgn(&rgn); rgn.DeleteObject(); // l'actuce centrale: // laisse le controle se redessiner dans le DC en memoire CWnd::DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 ); // definition des couleurs : // COLORREF m_clrTextColor=RGB(255,0,0); // COLORREF m_clrSelBkColor=RGB(192,192,192); // COLORREF m_clrSelTextColor=RGB(128,0,0); HTREEITEM hItem = GetFirstVisibleItem(); UINT selflag = TVIS_DROPHILITED | TVIS_SELECTED; int n = GetVisibleCount()+1; // selection de la fonte courante CFont *pFont = GetFont(); CFont *pOldFont=memDC.SelectObject(pFont); // parcours des items while( hItem && n--) { CRect rect; CString str= GetItemText( hItem ); GetItemRect( hItem, &rect, TRUE ); int nsav=memDC.SaveDC(); // sauvegarde des attributs du DC // Item non selectionné if(!(GetItemState( hItem, selflag ) & selflag )) { // couleur d'ecriture memDC.SetTextColor(m_clrTextColor); } else { // ignorer ce bloc si on veut garder la selection standard blanc sur fond bleu. // item en selection memDC.SetBkColor(m_clrSelBkColor); // fond memDC.SetTextColor(m_clrSelTextColor);// ecriture } // pour repeindre le fond CBrush brush,*pOldBrush; brush.CreateSolidBrush(memDC.GetBkColor()); memDC.FillRect(rect,&brush); memDC.TextOut( rect.left+2, rect.top+1, str ); memDC.RestoreDC(nsav); // restauration du DC hItem = GetNextVisibleItem( hItem ); } memDC.SelectObject(pOldFont); // ecriture finale du bitmap. dc.BitBlt( rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), &memDC, rcClip.left, rcClip.top, SRCCOPY ); }
merci , ca marche exactement comme je le voulais.
SBP
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager