[C / Win32] Listbox en ownerdraw : Comment changer les couleurs (fond et texte)

Résolu
Inekman
Messages postés
291
Date d'inscription
dimanche 2 février 2003
Statut
Membre
Dernière intervention
30 juin 2006
- 16 janv. 2006 à 01:05
Inekman
Messages postés
291
Date d'inscription
dimanche 2 février 2003
Statut
Membre
Dernière intervention
30 juin 2006
- 16 janv. 2006 à 18:23
Bonsoir à tous,

Je cherche déseprérément à changer les couleurs des items d'une listbox (blanc sur fond rouge par exemple). J'ai trouvé pêle-mêle des API à utiliser, à savoir WM_DRAWITEM voir WM_MEASUREITEM, des structures DRAWITEMSTRUCT et autres. Par contre je ne trouve pas d'exemples --> simples <-- qui m'expliquent clairement comment tout cela doit être imbriqué.

Pour info complémentaire, je dirais que chaque item de la zone de liste peut avoir une valeur (passée par LB_SETITEMDATA) comprise entre 0 et 3 en sachant que 0 et 1 donne un fond rouge et 2 et 3 donne un fond noir. (histoire de cadrer la demande)

Voilà, si vous savez des choses là-dessus, merci de bien vouloir m'aider.

Inek.

6 réponses

cs_aardman
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
3
16 janv. 2006 à 17:00
Salut,

Pour une listbox ownerdraw la valeur associée se passe lors du LB_INSERTSTRING.

WM_MEASUREITEM: Tu n'est pas obligé de traiter ce message, sauf si tu
veux modifier la taille d'un item. Pour modifier la hauteur de tout les
items tu peux toujours utiliser LB_SETITEMHEIGHT.



WM_DRAWITEM:

La structure DRAWITEMSTRUCT te donne tout ce dont tu as besoin, le dc le rectangle, le status, le focus..



Exemple:

J'ai defini une structure qui contient les infos de l'item (texte, couleur, brush).

Pour chaque item on alloue et on remplie une structure LBITEM.

On ajoute un item en passant un pointeur sur cette structure dans le LB_INSERTSTRING.

Lors du WM_DRAWITEM, on recupere ce pointeur dans le champ itemData de la structure DRAWITEMSTRUCT, et on dessine..



Structure:

typedef struct _LBITEM

{

LPTSTR text; // texte de l'item

COLORREF textcolor; // couleur du texte

HBRUSH bgbrush; // brush pour dessiner le fond de l'item

} LBITEM, *PLBITEM;



Traitement du WM_DRAWITEM:

LPDRAWITEMSTRUCT info = (LPDRAWITEMSTRUCT) lParam;

PLBITEM item = (PLBITEM) info->itemData;



SetTextColor(info->hDC, item->textcolor);

SetBkMode(info->hDC, TRANSPARENT);



FillRect(info->hDC, &info->rcItem, item->bgbrush);

DrawText(info->hDC, item->text, -1, &info->rcItem, DT_SINGLELINE | DT_VCENTER | DT_CENTER);



Biensur ca reste tres basique, puisqu'on ne prend pas compte du focus et de la selection lors du dessin.









<link href="../../../../css/ie4.css" type="text/css" rel="stylesheet"><!-- @ --><link href="../../../../css/inetsdk.css" type="text/css" rel="stylesheet"><!-- @ --><style type="text/css">
PRE.clsCode { font-size:110%; }
PRE.clsSyntax { font-size:100%; }
TD DIV.clsBeta { display:none;}

A:link { color:#0000ff; text-decoration:underline;}
A:visited { color:#0000ff; text-decoration:underline;}
A:hover { color:#3366ff; text-decoration:underline;}
MSHelp\:link {
color:#0000ff;
text-decoration:underline;
cursor:hand;
hoverColor:#3366ff;
filterString: ;}
</style><link href="ms-help://Hx/HxRuntime/HxLink.css" type="text/css" rel="stylesheet"><XML id="_topicdata" pagetype="winmsg" proj="platsdk" name="LB_INSERTSTRING" pubpath="/platform/commctls/listboxes/listboxreference/listboxmessages/lb_insertstring.htm"><!-- topic data --><root></root></XML><xml xmlns:mshelp="http://msdn.microsoft.com/mshelp"></xml>
3
cs_aardman
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
3
16 janv. 2006 à 18:11
Salut,

Ben pour colorier le fond c'est le FillRect() qui fait ca.

Si tu dessines du texte par dessus faut penser a faire le SetBkMode(info->hDC, TRANSPARENT);

Et pour l'emplacement du texte, il faut regarder dans msdn tout les
flags dispo pour le dernier param de DrawText(), dans l'exemple j'ai
mis DT_VCENTER | DT_CENTER donc le texte devrait s'afficher en plein
milieux du rectangle de l'item.
3
Inekman
Messages postés
291
Date d'inscription
dimanche 2 février 2003
Statut
Membre
Dernière intervention
30 juin 2006

16 janv. 2006 à 18:23
Oui oui je me suis renseigné dans le SDK. Pour mon projet, je les ai donc mis en DT_LEFT, sauf qu'ils sont beaucoup trop à gauche en fait. En mode normal, y'a comme une marge de 1 ou 2 pixel entre le bord et le caractère alors qu'en ownerdraw le texte est complètement collé contre le bord.

J'ai testé un truc avant de poster ce message et j'ai trouvé comment faire :

RECT rcTxt;

rcTxt = info->rcItem;
rcTxt.left += 3;

FillRect(info->hDC, &info->rcItem, fond);
DrawText(info->hDC, ligne, -1, &rcTxt, DT_SINGLELINE | DT_LEFT | DT_VCENTER);

Et voilà, ça marche.

Donc pour finir, un ENORME MERCI pour aardman car j'en ai bouffé des sites à propos de l'ownerdraw et voilà seulement que je comprend !

Tous mes meilleurs voeux pour 2006 aardman.
3
Inekman
Messages postés
291
Date d'inscription
dimanche 2 février 2003
Statut
Membre
Dernière intervention
30 juin 2006

16 janv. 2006 à 01:07
--> En parlant maladroitement d'API, je faisais en fait référence aux messages à traiter. Cependant l'essentiel est dit dans le post.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_Arnotic
Messages postés
933
Date d'inscription
dimanche 1 avril 2001
Statut
Membre
Dernière intervention
9 janvier 2012
1
16 janv. 2006 à 16:36
Il sufftit d'aller dans la documentation de MSDN concernant ce control et tu as des exemples expliqués.
http://msdn.microsoft.com/library

@+
Arnotic,
Admin CS,
http://dev.winsysdev.com
MVP Visual C++
0
Inekman
Messages postés
291
Date d'inscription
dimanche 2 février 2003
Statut
Membre
Dernière intervention
30 juin 2006

16 janv. 2006 à 17:54
Merci beaucoup aardman, j'ai réussi à me baser sur ton code pour récupérer le contenu des items de la zone de liste. Pour mon projet, j'ai une liste chaînée de structures qui contiennent le texte à afficher, donc j'ai réutilisé ça.

Maintenant, le texte s'affiche complètement à gauche de la liste et la 1ère lettre de chaque ligne est légèrement rognée.

J'ai le texte, c'est déjà une bonne chose, je dois maintenant essayé de colorier le fond des items :)
0