ListView Sortieren



  • Hallo, ich habe ein kleines Problem.
    Ich nutze folgeneden Code um eine ListView zu sortieren, das problem dabei: Es wird immer nur die erste Spalte sortiert, egal wo ich hin klicke...
    Ich bin mir sicher jemand von euch kann mir sofort sagen woran es liegt.

    #define NO_OF_SUBITEM 6
    #define UP 1
    #define DOWN 2
    
    typedef struct _tagSORTDATA{
        HWND hwndList;
        int isortSubItem;
        int iUPDOWN;
    } SORTDATA;
    
    SORTDATA SortData;
    static int sortsubno[NO_OF_SUBITEM] = {DOWN};
    static int isortsubno; 
    
    case WM_NOTIFY:
    			 switch (((LPNMHDR) lParam)->code) {
    				case LVN_COLUMNCLICK:
    					char test[100] = "";
    					NMLISTVIEW *lpnmlistview;
    					lpnmlistview = (LPNMLISTVIEW)lParam;
    					isortsubno = lpnmlistview->iSubItem;
    
    					if (sortsubno[isortsubno] == UP){
    						sortsubno[isortsubno] = DOWN;
    						MessageBox(NULL, "DOWN" , "Server Error", MB_OK);
    					} else{
    						MessageBox(NULL, "UP" , "Server Error", MB_OK);
    						sortsubno[isortsubno] = UP;
    					}
    					SortData.hwndList = hwndList;
    					SortData.isortSubItem = isortsubno;
    					SortData.iUPDOWN = sortsubno[isortsubno];
    					if(ListView_SortItemsEx(hwndList, MyCompProc, &SortData) != TRUE)
    						MessageBox(hwndMain, "?????", "Error", MB_OK);
    
    				break;
    			  }
    			break;
    
    int CALLBACK MyCompProc(LPARAM lp1, LPARAM lp2, LPARAM lp3)
    {
        static LVFINDINFO lvf;
        static int nItem1, nItem2;
        static char buf1[MAX_PATH], buf2[MAX_PATH];
        SORTDATA *lpsd;
    
        lpsd = (SORTDATA *)lp3;
    
        lvf.flags = LVFI_PARAM;
        lvf.lParam = lp1;
        nItem1 = ListView_FindItem(lpsd->hwndList, -1, &lvf);
    
        lvf.lParam = lp2;
        nItem2 = ListView_FindItem(lpsd->hwndList, -1, &lvf);
    
        ListView_GetItemText(lpsd->hwndList, nItem1, lpsd->isortSubItem, buf1, sizeof(buf1));
    
        ListView_GetItemText(lpsd->hwndList, nItem2, lpsd->isortSubItem, buf2, sizeof(buf2));
    
        if(lpsd->iUPDOWN == UP)
            return(stricmp(buf1, buf2));
        else
            return(stricmp(buf1, buf2) * -1);
    }
    

    Danke und Gruss



  • Genau das selbe habe ich vor einer Stunde gemacht 🙂

    case LVN_COLUMNCLICK:
    	{
    		LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam;
    		Sort.Colum = pnmv->iSubItem; [b]// Die Spalte wo geklickt wurde![/b]
    		SendMessage(lpnmh->hwndFrom, LVM_SORTITEMS, (WPARAM) &Sort, reinterpret_cast<LPARAM>(CompareFunc));
    		Sort.Asc = !Sort.Asc;
    		return TRUE;
    	}
    

    Such dir die Spalte raus und reagier darauf!

    schirrmie



  • Was meinst du mit "darauf reagieren"? Soll ich für jede Spalte eine individuelle Sortierfunktion schreiben?



  • Kannst du natürlich auch oder du machst das wie ich 😉
    Du übergibst die Spalte mit deiner "Sortierstruktur" die du ja auch hast. in meinem Fall

    Sort.Colum = pnmv->iSubItem; // Die Spalte wo geklickt wurde!
    

    und meine Sortierfunktion sieht dann so aus

    int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
    {
    	...
    	SortStruct *sort = (SortStruct*) lParamSort;
    	...
    
    	switch( sort->Colum ) {
    	case 0: // erste Spalte
    		...
    		break;
    	case 1: // zweite Spalte
    		...
    		break;
    	case 2: // dritte Spalte
    		...
    		break;
    	default:
    		return 0;
    	}
    	return 0;
    }
    

    schirrmie



  • Wunderschön, ich habe mal deinen Ansatz verfolgt bis ich gemerkt habe, dass ich gar keine Differenzierung brauche. Hier mein Code:

    Aufruf:

    ListView_SortItemsEx(hwndList, MyCompProc, sortNo); //Letzer Parameter: Spalte wo geklickt wurde
    

    Callback:

    int CALLBACK MyCompProc(LPARAM lp1, LPARAM lp2, LPARAM lParamSort)
    {
        char buf1[30], buf2[30];
    
    	ListView_GetItemText(hwndList, lp1, lParamSort, buf1, sizeof(buf1));
    
    	ListView_GetItemText(hwndList, lp2, lParamSort, buf2, sizeof(buf2));
    
        if(SortData.iUPDOWN == UP)
            return(stricmp(buf1, buf2));
        else
            return(stricmp(buf1, buf2) * -1);
    }
    

    Danke für deine Hilfe auf jeden Fall.


Anmelden zum Antworten