[MFC] Tri special

Tri special [MFC] - C++ - Programmation

Marsh Posté le 11-06-2003 à 10:39:28    

Bonjour,
j'aimerai faire un tri sur une CListCtrl.
Voici comment elle se presente :
 
ligne 1 -> 14 .......
ligne 2 -> description1
ligne 3 -> 27 .....
ligne 4 -> 13 .....
ligne 5 -> 06 .....
ligne 6 -> description2
ligne 7 -> 09 .......
 
comme vous pouvez le voir, la ligne 2 est liee a la ligne 1 et la ligne 6 a la ligne 5.
Donc mon probleme est que quand je trie avec la methode SortItems, j'obtiens :
ligne 1 -> 06 .....
ligne 2 -> 09 ......
ligne 3 -> 13 .....
ligne 4 -> 14 .....
ligne 5 -> 27 .....
ligne 6 -> description1
ligne 7 -> description2
 
ce qui fait que mes lignes ne sont plus associees correctement.
Est ce que vous savez comment je pourrais faire pour obtenir le resultat que je veux? C'est a dire :
ligne 1 -> 06 .....
ligne 2 -> description2  
ligne 3 -> 09 ......
ligne 4 -> 13 .....
ligne 5 -> 14 .....
ligne 6 -> description1
ligne 7 -> 27 .....  
 
Merci beaucoup
 
Modifier la methode SortItems ne me parait pas tres facile. Voyez vous une autre solution?


Message édité par polo021 le 11-06-2003 à 10:40:53
Reply

Marsh Posté le 11-06-2003 à 10:39:28   

Reply

Marsh Posté le 11-06-2003 à 10:57:44    

Ben non. D'ailleurs, même en redéfinissant la méthode de tri, je vois pas comment tu pourrais obtenir ce que tu veux:
où est le lien entre les libellés "14" et "description1" au juste ?
Evidement, si tu peux modifier des libellés, mets plutôt ce genre de trucs : "14" et "14-description 1", par exemple.

Reply

Marsh Posté le 11-06-2003 à 11:17:26    

El_gringo a écrit :

Ben non. D'ailleurs, même en redéfinissant la méthode de tri, je vois pas comment tu pourrais obtenir ce que tu veux:
où est le lien entre les libellés "14" et "description1" au juste ?
Evidement, si tu peux modifier des libellés, mets plutôt ce genre de trucs : "14" et "14-description 1", par exemple.


je pense pas que je pourrais mettre tout sur la meme ligne. Je vais continuer a chercher une solution puis en dernier recours je verrais bien si je peux faire mon affichage en lignes

Reply

Marsh Posté le 11-06-2003 à 11:29:15    

Le mieux est de faire une hashtable et de trier les clés. Ensuite, tu parcours la hashtable et tu appliques l'algo suivant :
 
Si valeur(clé) != Null Alors InsérerLigne(valeur(clé));
 
Comme ça, si une valeur ne contient pas de ligne associée, tu n'auras pas de ligne supplémentaire, sinon la ligne associée sera insérée sous la valeur


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 11-06-2003 à 11:44:14    

Harkonnen a écrit :

Le mieux est de faire une hashtable et de trier les clés. Ensuite, tu parcours la hashtable et tu appliques l'algo suivant :
 
Si valeur(clé) != Null Alors InsérerLigne(valeur(clé));
 
Comme ça, si une valeur ne contient pas de ligne associée, tu n'auras pas de ligne supplémentaire, sinon la ligne associée sera insérée sous la valeur
 


ca peut m'etre utile, je vais aller me renseigner sur le principe de la hashtable.
Merci

Reply

Marsh Posté le 11-06-2003 à 11:56:26    

je viens peut etre d'avoir une autre idee.  
Je vais d'abord tenter la solution suivante (toute simple)
je regroupe les elements de la liste sur une seule ligne et je les insere dans une nouvelle liste
donc:  
ligne 1 -> 06 ..... description 1
...
 
puis je la trie (plus de probleme pour le tri)
et je reparcours la liste triee en reinserant les items tries sur deux lignes dans l'ancienne liste.
Je sais pas si c'est clair comme explication mais je vais essaer ca.
[:neowen]

Reply

Marsh Posté le 11-06-2003 à 12:07:06    

polo021 a écrit :

Donc mon probleme est que quand je trie avec la methode SortItems...
 
...Modifier la methode SortItems ne me parait pas tres facile. Voyez vous une autre solution?


 
Pas besoin de modifier la méthode SortItems ! En effet, cette méthode accepte une fonction en paramètre. A toi de te débrouiller pour implémenter cette fonction correctement. Il faut juste trouver un moyen de trier en fonction de la donnée associée à chaque item (voir SetItemData/GetItemData).
 
On peut imaginer que tu stockes dans la donnée associée à chaque item la valeur de l'item pour les items "standards" (en renvoyant 'lParam1 - lParam2') et peut être un flag pour indiquer que c'est une description.
 
On aurait ainsi :

Code :
  1. #define DESCRIPTION_MASK 0x80000000
  2. item | texte          | lParam
  3. 1    | "14"           | 14
  4. 2    | "description1" | (14 | DESCRIPTION_MASK)
  5. 3    | "27"           | 27
  6. 4    | "13"           | 13
  7. 5    | "06"           | 6
  8. 6    | "description2" | (6 | DESCRIPTION_MASK)
  9. 7    | "09"           | 9
  10. int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
  11. {
  12. int res = (lParam1 ^ DESCRIPTION_MASK) - (lParam2 ^ DESCRIPTION_MASK); // compare les deux paramètres sans le masque
  13. if( res == 0 ) // si les deux params étaient égaux
  14. { // un des deux doit être la description
  15. if( (lParam1 & DESCRIPTION_MASK) == DESCRIPTION_MASK )
  16. res = 1; // si c'est lParam1, je le met après
  17. else
  18. res = -1; // sinon, je met lParam1 avant
  19. }
  20. return res;
  21. }


 
J'ai pas fait de tests, mais j'imagine que ça doit marcher. C'est une approche qui a l'avantage d'être assez rapide (la fonction de tri est simple), mais qui n'utilise le lParam que pour le tri et tu ne peux pas utiliser le bit DESCRIPTION_MASK dans tes valeurs. Si les inconvénients sont trop importants, il reste la solution d'affecter à lParam un pointeur vers une structure et là tu peut faire ce que tu veux.


---------------
each day I don't die is cheating
Reply

Marsh Posté le 11-06-2003 à 16:43:33    

gatorette a écrit :


 
Pas besoin de modifier la méthode SortItems ! En effet, cette méthode accepte une fonction en paramètre. A toi de te débrouiller pour implémenter cette fonction correctement. Il faut juste trouver un moyen de trier en fonction de la donnée associée à chaque item (voir SetItemData/GetItemData).
 
On peut imaginer que tu stockes dans la donnée associée à chaque item la valeur de l'item pour les items "standards" (en renvoyant 'lParam1 - lParam2') et peut être un flag pour indiquer que c'est une description.
 
On aurait ainsi :

Code :
  1. #define DESCRIPTION_MASK 0x80000000
  2. item | texte          | lParam
  3. 1    | "14"           | 14
  4. 2    | "description1" | (14 | DESCRIPTION_MASK)
  5. 3    | "27"           | 27
  6. 4    | "13"           | 13
  7. 5    | "06"           | 6
  8. 6    | "description2" | (6 | DESCRIPTION_MASK)
  9. 7    | "09"           | 9
  10. int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
  11. {
  12. int res = (lParam1 ^ DESCRIPTION_MASK) - (lParam2 ^ DESCRIPTION_MASK); // compare les deux paramètres sans le masque
  13. if( res == 0 ) // si les deux params étaient égaux
  14. { // un des deux doit être la description
  15. if( (lParam1 & DESCRIPTION_MASK) == DESCRIPTION_MASK )
  16. res = 1; // si c'est lParam1, je le met après
  17. else
  18. res = -1; // sinon, je met lParam1 avant
  19. }
  20. return res;
  21. }


 
J'ai pas fait de tests, mais j'imagine que ça doit marcher. C'est une approche qui a l'avantage d'être assez rapide (la fonction de tri est simple), mais qui n'utilise le lParam que pour le tri et tu ne peux pas utiliser le bit DESCRIPTION_MASK dans tes valeurs. Si les inconvénients sont trop importants, il reste la solution d'affecter à lParam un pointeur vers une structure et là tu peut faire ce que tu veux.


 
merci bcp pour ton aide, je vais essayer a partir de tes explications et de ton exemple  :jap:
 
A quoi sert description mask au juste?


Message édité par polo021 le 11-06-2003 à 16:47:32
Reply

Marsh Posté le 11-06-2003 à 17:45:36    

polo021 a écrit :


A quoi sert description mask au juste?


 

Code :
  1. #define DESCRIPTION_MASK 0x80000000
  2. // soit en binaire : 10000000 00000000 00000000 00000000


 
En gros, si le bit de poids fort de mon lParam (qui fait 32 bits sur Windows 9x/NT hors versions 64 bits) est à 1, alors je sais que j'ai affaire à une description. Sinon, il s'agit d'une valeur.
L'inconvénient, c'est que cela ne te laisse plus que 31 bits pour stocker tes valeurs.


---------------
each day I don't die is cheating
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed