IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MFC Discussion :

Tri rapide d'une CListCtrl


Sujet :

MFC

  1. #21
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Montre aussi ton appel.

  2. #22
    Membre éclairé Avatar de vanitom
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    327
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 327
    Par défaut
    Voilà toute ma fonction de tri.

    void TknoListCtrlEx::Sort ( int nCol, BOOL bAsc )
    {
    CWaitCursor wc; wc.Restore ( );

    TknoListCtrlColEx * pColumn = (TknoListCtrlColEx *) GetColumn ( nCol, FALSE );
    ASSERT ( pColumn );
    if ( pColumn == NULL )
    return;

    SortBase::m_nCol = nCol;
    SortBase::m_bAsc = bAsc;

    switch ( pColumn->GetCompareType ( ) )
    {
    case TKNOLISTCTRLCOLEX_COMPARE_BYTEXT :
    sort ( m_vRows.begin ( ), m_vRows.end ( ), SortByText() );
    break;
    case TKNOLISTCTRLCOLEX_COMPARE_BYNUMERIC :
    sort ( m_vRows.begin ( ), m_vRows.end ( ), SortByNumeric() );
    break;
    }

    SetSortColumn ( nCol, bAsc );

    Invalidate ( );
    }

  3. #23
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    C'est encore plus simple:m_nCol et m_bAsc n'ont pas besoin d'être static. Il suffit de les fournir au contructeur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    sort ( m_vRows.begin ( ), m_vRows.end ( ), SortByText(nCol,bAsc) );
    // ou
    sort ( m_vRows.begin ( ), m_vRows.end ( ), SortByNumeric(nCol,bAsc) );
    Avec:
    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
     
    class TknoListCtrlEx :
    	public TknoListCtrl
    {
    [...]
    	struct SortBase {
    		public:		
    			int				m_nCol;
    			BOOL				m_bAsc;
                            SortBase(int P_nCol, BOOL P_bAsc):
                              m_nCol(P_nCol),m_bAsc(P_bAsc)
                             {}
    	};
     
    	struct SortByText : public SortBase
    	{
               SortByText(int P_nCol, BOOL P_bAsc):SortBase(P_nCol,P_bAsc)
               {}
    [...]
    	};
     
    	struct SortByNumeric : public SortBase
    	{
                 SortByNumeric(int P_nCol, BOOL P_bAsc):SortBase(P_nCol,P_bAsc)
                 {}
    [...]
    	};
    }

  4. #24
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Voir carrément:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class TknoListCtrlEx :
    	public TknoListCtrl
    {
    [...]
       template<int TypeTri>
    	struct Sort{
    		public:		
    			int				m_nCol;
    			BOOL				m_bAsc;
             Sort(int P_nCol, BOOL P_bAsc):m_nCol(P_nCol),m_bAsc(P_bAsc){}
             bool operator ()(TknoListCtrlRow& rRow1, TknoListCtrlRow& rRow2)
    	};
    };
    Puis l'implémentation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template<> 
    bool TknoListCtrlEx::TknoListCtrl<TKNOLISTCTRLCOLEX_COMPARE_BYTEXT>::operator ()(TknoListCtrlRow& rRow1, TknoListCtrlRow& rRow2)
    {
    [...]
    }
     
     
    template<> 
    bool TknoListCtrlEx::TknoListCtrl<TKNOLISTCTRLCOLEX_COMPARE_BYNUMERIC>::operator ()(TknoListCtrlRow& rRow1, TknoListCtrlRow& rRow2)
    {
    [...]
    }
    Et enfin, l'utilisation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    switch ( pColumn->GetCompareType ( ) )
    {
    case TKNOLISTCTRLCOLEX_COMPARE_BYTEXT :
    sort ( m_vRows.begin ( ), m_vRows.end ( ), Sort<TKNOLISTCTRLCOLEX_COMPARE_BYTEXT>(nCol,bAsc) );
    break;
    case TKNOLISTCTRLCOLEX_COMPARE_BYNUMERIC :
    sort ( m_vRows.begin ( ), m_vRows.end ( ), Sort<TKNOLISTCTRLCOLEX_COMPARE_BYNUMERIC>(nCol,bAsc) );
    break;
    }
    A noter:
    1/J'ai mis template<int TypeTri>, mais si c'est un enum tu peux aussi faire template<MonEnum TypeTri>
    2/ Lors de l'instanciation de Sort<> tu ne peux lui fournir en paramètre du template le résultat de ta fonction. Ce doit être une constante évaluée à la compilation (à un chouia près, c'est la norme). C'est pourquoi, je maintient le switch. Tu peux, au mieux utiliser un define:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #define ADD_CASE(IdCase)\
       case IdCase:\
       sort ( m_vRows.begin ( ), m_vRows.end ( ), Sort<IdCase>(nCol,bAsc) );\
       break
     
    switch ( pColumn->GetCompareType ( ) )
    {
    ADD_CASE(TKNOLISTCTRLCOLEX_COMPARE_BYTEXT);
    ADD_CASE(TKNOLISTCTRLCOLEX_COMPARE_BYNUMERIC);
    }
    A noter, enfin, que souvent, les normes de qualités imposent un default dans tous les switch/case. Tu peux y ajouter un ASSERT en debug.

  5. #25
    Membre éclairé Avatar de vanitom
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    327
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 327
    Par défaut
    J'adore ça me parai tellement simple. :yaisse2: Mais il fallait y penser.

    Par contre j'ai une dernière question pure MFC.
    En fait ma liste n'est utilisable que si elle est définie dans les resources avec LVS_REPORT et LVS_OWNERDATA.
    Et ça me gonfle de faire les modifications à chaque fois.

    J'aimerai donc modifier les styles de ces futures directement en Report et en OwnerData.
    J'ai bien compris que si la liste est créée avec les resources, le "PreCreateWindow" n'est jamais appelé. J'ai testé et je passe dans le "PreSubclassWindow". J'avais cru comprendre que je pouvais faire la modification du style. Mais ça ne fonctionne pas.

    void TknoListCtrlEx::PreCreateWindow ( )
    {
    ModifyStyle ( LVS_ICON | LVS_LIST, LVS_REPORT | LVS_OWNERDATA );

    TknoListCtrl::PreCreateWindow ( );
    }
    J'ai même essayé en mettant le "ModifyStyle" avant et après. Et toujours rien.

    Auriez vous une idée ?

  6. #26
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Je ne suis pas sûr que LVS_OWNERDATA puisse se changer dynamiquement, mais normalement LVS_REPORT, si.
    Enfin, un rechercher/remplacer va des fois bien plus vite que de chercher une solution un peu complexe.

  7. #27
    Membre éclairé Avatar de vanitom
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    327
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 327
    Par défaut
    Je viens de voir ton code optimiser encore plus le code. Ouais c'est impressionnant mais j'avoue que c'est trop pour moi.
    Accessoirement je ne vois pas l'utilité de complexifier le code à ce point. Mais je peux me tromper.

    Je trouve ça extrême pour les quelques fonctions de tri que j'ai besoin.

    Surtout que j'aime bien l'idée d'avoir un héritage comme c'est le cas actuellement.
    Ça me permet de réfléchir à une fonction de tri avec les dates.

    _____________________________


    Effectivement je suis d'accord, j'ai actuellement une fonction de validité pour vérifier que les deux configs sont bien active.
    Je crois que je vais finir par laisser ça comme ça.



    En tout cas merci à vous tous pour votre aide. Grâce à cette discussion j'ai réussi à faire ce que je voulais mais surtout j'ai beaucoup appris.

  8. #28
    Membre éclairé Avatar de vanitom
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    327
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 327
    Par défaut
    Je reviens vers vous pour une petite question.

    J'ai fais mes tests sur une liste de 100 000. C'est top ça marche.
    Je viens de l'intégrer et j'ai commencé par une petite liste pour ne pas pousser le bouchon trop loin.
    Et je viens de tomber sur un autre truc des stl. En fait pour fait fonctionner le sort, il me fallait un Predicate avec l'operateur "()". Mais là il me manque le ">" et le "<". En chargeant bien j'ai compris qu'en dessous de 32 lignes, le "sort" n'utilise pas le QuickSort mais le "InsertionSort".

    Avez vous déjà entendu parler de ça ou pas ?

  9. #29
    Membre éclairé Avatar de vanitom
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    327
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 327
    Par défaut
    Ça y est je viens de comprendre exactement ce qu'il se passe et c'est problématique.

    Ça vient du fait que plusieurs de mes chaines de caractères sont égales.

    Car lors du sort, l'algo utilise le Predicate pour réaliser une fonction "<". Cependant comme les 2 chaines testées sont égales, l'algo me met une erreur.

    Voici le code stl qui pose problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template<class _Pr, class _Ty1, class _Ty2> inline
    	bool __CLRCALL_OR_CDECL _Debug_lt_pred(_Pr _Pred, _Ty1& _Left, _Ty2& _Right,
    		const wchar_t *_Where, unsigned int _Line)
    	{	// test if _Pred(_Left, _Right) and _Pred is strict weak ordering
    	if (!_Pred(_Left, _Right))
    		return (false);
    	else if (_Pred(_Right, _Left))
    		_DEBUG_ERROR2("invalid operator<", _Where, _Line);
    	return (true);
    	}
    En cherchant un peu, beaucoup, on a trouvé que lorsque les 2 éléments d'un Predicate sont égaux, il faut ABSOLUMENT retourner "false".

    J'ai donc effectué cette vérification supplémentaire et c'est bon ça fonctionne de nouveau.

  10. #30
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par vanitom Voir le message
    Ça vient du fait que plusieurs de mes chaines de caractères sont égales.
    Effectivement, je n'avais jamais fait attention à la ligne (pourtant en italique) comme quoi l'opérateur de comparaison doit suivre la condition de strict weak ordering. D'ailleurs, on retrouve dans STL Précis&Concis de Ray Lischner, on trouve: la fonction de comparaison doit suivre l'ordre faible strict et en particulier A<A est toujours faux!

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Tri rapide d'une grille (TStringGrid)
    Par Pierre Castelain dans le forum Codes sources à télécharger
    Réponses: 1
    Dernier message: 01/02/2013, 09h08
  2. Réponses: 13
    Dernier message: 25/04/2012, 18h04
  3. [MFC] surbrillance de ligne dans une CListCtrl
    Par Yoshette dans le forum MFC
    Réponses: 4
    Dernier message: 15/04/2005, 16h09
  4. Tri rapide
    Par DBBB dans le forum Algorithmes et structures de données
    Réponses: 11
    Dernier message: 10/12/2004, 17h54
  5. Selectionner ligne dans une ClistCtrl
    Par fr66 dans le forum MFC
    Réponses: 2
    Dernier message: 03/05/2004, 14h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo