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

Inekman 292 Messages postés dimanche 2 février 2003Date d'inscription 30 juin 2006 Dernière intervention - 16 janv. 2006 à 01:05 - Dernière réponse : Inekman 292 Messages postés dimanche 2 février 2003Date d'inscription 30 juin 2006 Dernière intervention
- 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.
Afficher la suite 

6 réponses

Répondre au sujet
cs_aardman 1905 Messages postés mercredi 22 janvier 2003Date d'inscription 17 septembre 2012 Dernière intervention - 16 janv. 2006 à 17:00
+3
Utile
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>
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_aardman
cs_aardman 1905 Messages postés mercredi 22 janvier 2003Date d'inscription 17 septembre 2012 Dernière intervention - 16 janv. 2006 à 18:11
+3
Utile
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.
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_aardman
Inekman 292 Messages postés dimanche 2 février 2003Date d'inscription 30 juin 2006 Dernière intervention - 16 janv. 2006 à 18:23
+3
Utile
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.
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Inekman
Inekman 292 Messages postés dimanche 2 février 2003Date d'inscription 30 juin 2006 Dernière intervention - 16 janv. 2006 à 01:07
0
Utile
--> En parlant maladroitement d'API, je faisais en fait référence aux messages à traiter. Cependant l'essentiel est dit dans le post.
Commenter la réponse de Inekman
cs_Arnotic 936 Messages postés dimanche 1 avril 2001Date d'inscription 9 janvier 2012 Dernière intervention - 16 janv. 2006 à 16:36
0
Utile
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++
Commenter la réponse de cs_Arnotic
Inekman 292 Messages postés dimanche 2 février 2003Date d'inscription 30 juin 2006 Dernière intervention - 16 janv. 2006 à 17:54
0
Utile
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 :)
Commenter la réponse de Inekman

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.