fredsor
Messages postés198Date d'inscriptionlundi 24 avril 2006StatutMembreDernière intervention 3 avril 2008
-
6 juin 2007 à 17:22
fredsor
Messages postés198Date d'inscriptionlundi 24 avril 2006StatutMembreDernière intervention 3 avril 2008
-
16 juil. 2007 à 15:44
Bonjour,
Je galere depuis plusieurs jours pour essayer de mettre des couleurs de fond a certaines lignes de ma listbox...
J'ai trouvé quelques exemples, utilisant notamment LB_INSERTSTRING, LB_SETITEMDATA et WM_DRAWITEM pour le faire
Mais d'apres les codes, ma listbox doit aovir l'attribut LBS_OWNERDRAWFIXED pour que WS_DRAWITEM soit bien executé (sinon je crois qu'il ne va jamais dedans)
Cependant, LBS_OWNERDRAWFIXED n'est pas reconnu sous mon evc++!!!!
Quelqu'un a une idée pourquoi?
Je fais du C en Win32 pour ceux qui n'avait pas compris ^^
hTab[i] = CreateWindowEx( WS_EX_CLIENTEDGE, TEXT("LISTBOX"), NULL,
WS_VISIBLE|WS_CHILD|LBS_NOTIFY|WS_VSCROLL|WS_TABSTOP|WS_BORDER|LBS_OWNERDRAWFIXED |LBS_USETABSTOPS,...);
racpp
Messages postés1910Date d'inscriptionvendredi 18 juin 2004StatutModérateurDernière intervention14 novembre 201416 6 juin 2007 à 23:59
Salut,
Cette constante est définie dans winuser.h. Tu peux essayer de l'ajouter en haut de ton code avec un #define:
#define LBS_OWNERDRAWFIXED 0x0010
J'espère que ça marchera pour toi.
fredsor
Messages postés198Date d'inscriptionlundi 24 avril 2006StatutMembreDernière intervention 3 avril 2008 7 juin 2007 à 09:30
J'ai bien rajouté ce que tu m'a di, mais toujours rien a l'horizon!! Help!!
Voici les bouts de code concerné :
#define LBS_OWNERDRAWFIXED 0x0010
// en haut de mon code comme tu me l'a di
--------------
typedef struct _LBITEM // structure définissant l'item
{
LPTSTR text; // texte de l'item
COLORREF textcolor; // couleur du texte
HBRUSH bgbrush; // brush pour dessiner le fond de l'item
} LBITEM, *PLBITEM;
----------------
case WM_DRAWITEM: //Dessin des lignes de la listbox {
LPDRAWITEMSTRUCT info = (LPDRAWITEMSTRUCT) lParam;
PLBITEM item = (PLBITEM) info->itemData;
FillRect(info->hDC, &info->rcItem, item->bgbrush);
DrawText(info->hDC, item->text, -1, &info->rcItem, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
}
-------------------------
Et a la creation de mon tableau :
hTab[i] = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("LISTBOX"), NULL, WS_VISIBLE|WS_CHILD|
LBS_NOTIFY|WS_VSCROLL||WS_BORDER| LBS_OWNERDRAWFIXED |LBS_USETABSTOPS,
"Remplissage" de mon tableau :
LBITEM lbitem = {maLigne , rouge , fondBleu } ;
int test=SendMessage(hTab[i], LB_INSERTSTRING, (WPARAM)0, (LPARAM)maLigne);
SendMessage(hTab[i], LB_SETITEMDATA, (WPARAM)test, (LPARAM)&lbitem);
J'insere sinon avec un LB_ADDSTRING qui affiche bien le texte aussi :
//SendDlgItemMessage(hWnd, i, LB_ADDSTRING, 0, (LPARAM)maLigne);
Voila, je dois faire quelque chose, ou ne pas faire quelque chose, qui fait que WM_DRAWITEM ne semble jamais appelé??? Car les item sont bien "rempli" avec le texte, mais pas de couleur!!
ou alors c'est que le #define LBS_OWNERDRAWFIXED m'enleve juste l'erreur mais ne fonctionne pas??
SNIF SNIF!!!!
fredsor
Messages postés198Date d'inscriptionlundi 24 avril 2006StatutMembreDernière intervention 3 avril 2008 8 juin 2007 à 08:47
Oh moi qui me faisait une joie de voir une reponse, ca commence a me faire peur tout ca!!
Comment je peux verifier ca?
Et si ce que tu suppose se vérifie, comment je peux remedier a cela pour tout de meme mettre des couleurs a mes items de listbox? C'est le dernier truc qui me reste a géré sur ces listbox : mes focus sur les lignes voulues fonctionnent, et j'ai également créer des "colonnes" à l'aide de LBS_USETABSTOPS...
fredsor
Messages postés198Date d'inscriptionlundi 24 avril 2006StatutMembreDernière intervention 3 avril 2008 8 juin 2007 à 09:01
"Windows CE .NET provides the ability to change the user-interface skin of the operating system. This is similar to the concept of owner-draw controls, by which a Win32 program can change the appearance of various controls like push buttons, status bars, header controls, ListView controls, and the Tab control. (The desktop supports other owner-drawn items, like the Listbox, that are not supported in Windows CE.) "
STP dis moi que j'ai une solution de rechange! help
fredsor
Messages postés198Date d'inscriptionlundi 24 avril 2006StatutMembreDernière intervention 3 avril 2008 9 juin 2007 à 11:45
Tu veux dire que j'utiliserais une listbox mais que j'insererai des item listview??
Je vois pa trop comment c'est possible
Sinon si tu sous entend utiliser directement une listview au lieu d'une listbox : windows Ce ne prend pa les listview
As tu un exemple d'insertion d'item listview dans une listbox?
fredsor
Messages postés198Date d'inscriptionlundi 24 avril 2006StatutMembreDernière intervention 3 avril 2008 9 juin 2007 à 18:38
Ok donc utiliser une listbox avec des items a la liste view si je comprends bien...
Je vais essayer, mais d'apres le code que j'ai posté dans mes premiers messages, comment verrai tu ca Omnia?
Je laisse tout tel quel, je dois seulement modifier mes SendMessage? mais faire des listbox.pszText... ne devrait pas trop lui plaire non?
Tu as l'air d'etre assez calé la dessus, donc je suis pres a ecouter tes conseils? ^^
fredsor
Messages postés198Date d'inscriptionlundi 24 avril 2006StatutMembreDernière intervention 3 avril 2008 10 juin 2007 à 13:48
Oki je vais regarder ton API, j'epsere m'en sortir ;)
Le souci c'est que j'ai peur que ma listbox, a partir du moment ou elle ne peut pas accepter le LBS_OWNERDRAWFIXED, elle ne passe jamais dans les messages de dessin justement.
Je vais regarder ta solution, peut etre que c'est tout simplement pas jouable sinon sous Windows CE...
fredsor
Messages postés198Date d'inscriptionlundi 24 avril 2006StatutMembreDernière intervention 3 avril 2008 10 juin 2007 à 14:22
Peux-tu m'expliquer rapidmeent en quoi consiste SetWindowLong en fait? car les exemple que j'ai vu consistent plutot en du redimensionnement de controle, ou des recuperations de champs texte...
De plus comme je le crains je pense que ma listbox doit avoir le champ LBS_OWNERDRAWFIXED, chose impossible sous Windows CE...
Et sinon , tu dis "puis tu crée ta boucle Windows", je ne saisis pas trop là non plus. Je suis désolé tu dois me prendre pour un nul
Si j'ai bien compris, le SetWindowLong doit se faire apres le création de la listbox, et le deuxieme parametre concerne ce qu'on veut justement modifier...?
Désolé je ne suis pas très clair mais la je ne maitrise pas du tout
fredsor
Messages postés198Date d'inscriptionlundi 24 avril 2006StatutMembreDernière intervention 3 avril 2008 11 juin 2007 à 09:36
ReSalut omnia, j'ai fais les modification ssur tes conseils, et l'exemple que tu m'a fourni,
cependant j'ai l'impression qu'il ne passe pas dans ma fonction ( j'ai mis des messageBox basiques pour vérifier qui ne se déclenchent pas). De plus, mes items reste désespérement blancs, tandis que maintenant le focus a disparu sur ceux pour lesquels je l'avait mis, et on peut maintenant en selectionner plusieurs :s
C'est sans doute une mauvaise manip' du SetWindowLong, c'est pourquoi je te montre les bouts de code sans doute responsable :
WNDPROC ListBoxProcSousClassement;
// déclaré en global
la fonction ListBoxProc :
LRESULT CALLBACK ListBoxProc(HWND hwnd, UINT Msg, WPARAM Wparam, LPARAM lParam)
{
// MessageBox(NULL,TEXT("listboxproc"),TEXT(""),MB_OK);
//traitement pour pour DrawItem
if (Msg = = WM_DRAWITEM)
{
// MessageBox(NULL,TEXT("drawitem"),TEXT(""),MB_OK);
SetTextColor((HDC)Wparam,rouge);
SetBkColor((HDC)Wparam,rouge);
return (BOOL) fondRouge;
}
//retour la fonction de gestion de la listbox
return CallWindowProc(ListBoxProcSousClassement, hwnd, Msg, Wparam, lParam);
}
et dans mon WM_CREATE :
hTab[i] = CreateWindowEx( WS_EX_CLIENTEDGE, TEXT("LISTBOX"), NULL,
WS_VISIBLE|WS_CHILD|LBS_NOTIFY|WS_VSCROLL|WS_BORDER|BS_OWNERDRAW|LBS_USETABSTOPS|WS_TABSTOP,
atoi(GetAbscisse(i)),atoi(GetOrdonnee(i))+15, atoi(GetLargeur(i,"T")), atoi(GetHauteur(i,"T"))-5,
hWnd, HMENU(i), hinst, NULL);
le BS_OWNERDRAW n'apporta pes d'erreur,c'es deja un bon point ;)
puis pour ajouter mes items apres quelques calculs :
SendDlgItemMessage(hWnd, i, LB_ADDSTRING, 0, (LPARAM)affichageLigne);
SendMessage(hTab[i], LB_SETTABSTOPS, indiceColonne+1, (LPARAM)stops);
ListBoxProcSousClassement = (WNDPROC)SetWindowLong(GetWindow(hTab[i],i), GWL_WNDPROC,(LONG)ListBoxProc);
Le premier Send permet d'ajouter la ligne, le second gère mes tabstop pour les colonnes et enfin le fameux SEtWindowLong
Cela vient peut etre du premier parametre du SetWindowLong? J'ai essayé un GetWindow, GetDlgItem, sans succès... Et pourtant j'ai l'impression que ta solution pourrait marcher!
Où me serais-je trompé a ton avis?
pour la réécriture du texte il faudra récupérer le texte précédement écrit puis le redessiné
voici un bout de code que j'utilise actuellement sur une listview a réadapter pour ta listbox:
case WM_DRAWITEM:
//traitement par ligne
lpDrawItem = (LPDRAWITEMSTRUCT)lParam;
//gestion de la sélection
if(ListView_GetItemState(HListView, lpDrawItem->itemID, LVIS_SELECTED) & LVIS_SELECTED)
{
// L'élément est séléctionné
FillRect(lpDrawItem->hDC, &lpDrawItem->rcItem, GetSysColorBrush(COLOR_HIGHLIGHT));
SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
}
else
{
FillRect(lpDrawItem->hDC, &lpDrawItem->rcItem, GetSysColorBrush(COLOR_WINDOW));
SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_MENUTEXT));
}
ListView_GetItemRect(HListView, lpDrawItem->itemID, &rect, LVIR_BOUNDS);
x = rect.left; // x dépend de la position de la scroll bar horizontalle
// en tous cas on a toujours x <= 0
rect.top = lpDrawItem->rcItem.top;
rect.bottom = lpDrawItem->rcItem.bottom;
//les 5 première colonnes
for (i=0;i<5;i++)
{
// nb colonne
y = ListView_GetColumnWidth(HListView, i);
rect.left = x + 2;
rect.right = x + y - 2;
//récupération du texte de l'item
ListView_GetItemText(HListView,lpDrawItem->itemID,i,tmp,TMP_DEFAULT);
DrawText(lpDrawItem->hDC,tmp, strlen(tmp), &rect, DT_VCENTER);
x += y;
}
// Dessine de 0 au %
rect.left = x + 1;
i = Progress[lpDrawItem->itemID] * (y - 1) / 100;
rect.right = x + i + 1;
rect.top = lpDrawItem->rcItem.top + 2;
rect.bottom = lpDrawItem->rcItem.bottom - 2;
if(Progress[lpDrawItem->itemID])
FillRect(lpDrawItem->hDC, &rect, Hb1);
// Dessin du % à 100
rect.left = x + i + 1;
rect.right = x + y - 1;
if(Progress[lpDrawItem->itemID] != 100)
FillRect(lpDrawItem->hDC, &rect, Hb2);
//ajout d'un test pour éviter que le texte ne disparaisse si l'item est sélectionné
if((ListView_GetItemState(HListView, lpDrawItem->itemID, LVIS_SELECTED) & LVIS_SELECTED) &&(Progress[lpDrawItem->itemID]<60))
{
// L'élément est séléctionné
SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_MENUTEXT));
}
//texte dans la barre de progression : 0%
rect.left = x+ y/2;
rect.right = x + y;
rect.bottom +=2;
rect.top-=2;
sprintf(tmp,"%d%%",Progress[lpDrawItem->itemID]);
DrawText(lpDrawItem->hDC,tmp, strlen(tmp), &rect, DT_VCENTER);
break;
fredsor
Messages postés198Date d'inscriptionlundi 24 avril 2006StatutMembreDernière intervention 3 avril 2008 11 juin 2007 à 11:19
Au bord de la crise de nerfs... meme si je peux m'estimer heureux que tu repondes encore (peut etre plus longtps! :D)
Bon alors, j'ai essayer tout basiquement sans gérer le focus, de mettre une meme couleur pour chaque item, tout simplement.
Et donc toujours rien, pourtant mon WM_DRAWITEM semble bien formé. comment je pourrais vérifier que mon prog asse bien dans ma fonction sous-classée? car j'ai vraimeent des doutes sur le fait qu'elle y passe bien (avec un débuggage, lorsque j'arrive sur la ligne l'appelant, le Ctrl+F11 passe directement a la ligne suivante, ne rentre pas dans la fonction...)
Mais cela est peut etre normale, meme si j'ai des doutes... Snif snif
J'ai remis ma strucure pour créer mes items, et changer mon WM_DRAWITEM, ainsi :
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;
............................................................................................................................ LRESULT CALLBACK ListBoxProc(HWND hwnd, UINT Msg, WPARAM Wparam, LPARAM lParam)
{
if (Msg = = WM_DRAWITEM)
{
LPDRAWITEMSTRUCT info = (LPDRAWITEMSTRUCT)lParam;
PLBITEM item = (PLBITEM) info->itemData;