Style-7 Ответов: 2

Управление представлением списка, сортировка столбца строки?


Привет,
Мне нужно отсортировать элемент управления представлением списка по строковому столбцу.
Я знал сообщение LVM_SORTITEMS.
и имейте функцию сравнения

Так
1. Я должен скопировать все элементы массива строк
2. Установите для всех элементов lparam значение индекса массива
3. Отправить сообщение LVM_SORTITEMS

char myArray[100][MAX_PATH]; //for example static array for store

int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort){
   int ind_1 = int( lParam1 );
   int ind_2 = int( lParam2 );
   return lstrcmp( myArray[ind_1], myArray[ind_2]);
}

Хорошо или это неправильный путь?

2 Ответов

Рейтинг:
13

enhzflep

Когда мне нужно это сделать, я использую lParam каждого элемента, добавленного в listView, чтобы указать на структуру, содержащую сам элемент. Таким образом, в функции сравнения вы можете просто использовать два значения lParam для доступа ко всем данным, которые представляет каждый элемент в listView.
Это позволяет вам (например) использовать параметр lParamSort как способ сообщить вашей функции сортировки, как себя вести. Я часто использую это для обозначения столбца, на котором я хотел бы основать сортировку, используя отрицательное или положительное значение для обозначения направления.

Вот addItems func и sortFunc, который идет с этим listView



/////// Example Add items to lisstView ////////
    if (numItems != 0)
    {
        HWND lvWnd = GetDlgItem(mainDlgHwnd, IDC_ITEM_LIST);

        clearListView(lvWnd);
        for (int i=0; i<numitems;>        {
            addListViewItem(lvWnd,
                            (char*)makeNiceDate(curFeedItems[i].pubdate).c_str(),
                            (char*)curFeedItems[i].title.c_str(),
                            (char*)curFeedItems[i].author.c_str(),
                            (LPARAM)&curFeedItems[i]);
        }
    }

/////// Example sort ////////
	lParamSort = 1 + nSortColumn;
	if (!bSortAscending)
		lParamSort = -lParamSort;

	// sort list
	ListView_SortItems(pLVInfo->hdr.hwndFrom, myCompFunc, lParamSort);




typedef struct
{
    string title;
    string description;
    string link;
    string author;
    string pubdate;
    string subject;
} rssItem_t;



void addListViewItem(HWND listView, char *timeStr, char *titleStr, char *authorStr, LPARAM ptrToInRssItem)
{
    LV_ITEM newItem;
    int insertIndex;

    insertIndex = ListView_GetItemCount(listView);

    newItem.mask = LVIF_TEXT|LVIF_PARAM;
    newItem.iItem = insertIndex;
    newItem.pszText = timeStr;
    newItem.cchTextMax = strlen(timeStr);
    newItem.iSubItem = 0;
    newItem.lParam = ptrToInRssItem;
    insertIndex = SendMessage(listView, LVM_INSERTITEM, 0, (LPARAM)&newItem);

    newItem.mask = LVIF_TEXT;
    newItem.pszText = titleStr;
    newItem.cchTextMax = strlen(titleStr);
    newItem.iSubItem = 1;
    SendMessage(listView, LVM_SETITEM, 0, (LPARAM)&newItem);

    newItem.mask = LVIF_TEXT;
    newItem.pszText = authorStr;
    newItem.cchTextMax = strlen(authorStr);
    newItem.iSubItem = 2;
    SendMessage(listView, LVM_SETITEM, 0, (LPARAM)&newItem);
}








int CALLBACK myCompFunc(LPARAM lp1, LPARAM lp2, LPARAM sortParam)
{
    bool isAsc = (sortParam > 0);
    int column = abs(sortParam)-1;
    rssItem_t *item1, *item2;

    item1 = (rssItem_t*) lp1;
    item2 = (rssItem_t*) lp2;
    switch (column)
    {
        case 0:
            if (isAsc) return parseDateStr(item1->pubdate) - parseDateStr(item2->pubdate);
            else return parseDateStr(item2->pubdate) - parseDateStr(item1->pubdate);
            break;

        case 1:
            if (isAsc) return strcasecmp(item1->title.c_str(), item2->title.c_str());
            else return strcasecmp(item2->title.c_str(), item1->title.c_str());

        case 2:
            if (isAsc) return strcasecmp(item1->author.c_str(), item2->author.c_str());
            else return strcasecmp(item2->author.c_str(), item1->author.c_str());
            break;
    }
    return 0;
}


Рейтинг:
1

djshuman

// Global
int g_iNumColumns;
int g_iSortColumn;
BOOL g_bSortAscending;
static int CALLBACK CompareFunction( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort );


void CDlgListCtrl::OnColumnclickListCtrlAnalysis(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	// TODO: Add your control notification handler code here

	const int iColumn = pNMLV->iSubItem;
	// if it's a second click on the same column then reverse the sort order,
	// otherwise sort the new column in ascending order

	Sort( iColumn, iColumn == g_iSortColumn ? !g_bSortAscending : TRUE );

	*pResult = 0;
}


void CDlgListCtrl::Sort( int iColumn, BOOL bAscending )
{
	// Globo values used because the CALLBACK CompareFunction must be defined outside of the Class. 
	g_iSortColumn = iColumn;
	g_bSortAscending = bAscending;

	LVITEM lvItem;
	int n;

	for(n = 0; n < m_list_ctrl_analysis.GetItemCount(); n++ )
		{
			lvItem.mask = LVIF_PARAM;
//SortItems uses the lvItem.lParam to sort the CListCtrl 
//The lParam1 parameter is the 32-bit value associated with the first item that is 
// compared, and lParam2 parameter is the value associated with the second 
// item.
// The lParam1 and lParam2 were made the sames as the current nitem numbers for the 
// current ListCtrl table each time the column header is clicked to new sort.
			lvItem.lParam = (LPARAM)n;
			lvItem.iItem = n;
			lvItem.iSubItem = 0;

			m_list_ctrl_analysis.SetItem(&lvItem);
		}

	m_list_ctrl_analysis.SortItems( CompareFunction, (LPARAM)&m_list_ctrl) ; 
                                      // Or whatever you named your CListCtrl	
	}
	


int CALLBACK CompareFunction( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort )
{
	CListCtrl* pListCtrl = (CListCtrl*) lParamSort;
	int result;
 
	
	CString    strItem1 = pListCtrl->GetItemText(static_cast<int>(lParam1), g_iSortColumn);
    CString    strItem2 = pListCtrl->GetItemText(static_cast<int>(lParam2), g_iSortColumn);
   
// Add your own fancy comparison technique here, such as the date/time string. 

	if( g_bSortAscending == TRUE )
		result = strcmp(CStringA(strItem1), CStringA(strItem2));

	if( g_bSortAscending == FALSE )
		result = strcmp(CStringA(strItem2), CStringA(strItem1));

    return result;
}


Kats2512

всего на 8 лет опоздал!

CHill60

Необъяснимые дампы кода не являются решением проблемы