Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > Сортировка в CListCtrl


Автор: kometa_triatlon 2.6.2005, 03:02
Часто встречается такая фишка: рядом с названием одной из колонок CListCtrl ( стиль report ) есть небольшой треугольник. Нажатие на хидер устанавливает сортировку списка по этому полю, повторное нажатие меняет направление сортировки. Ну вы поняли о чем я. Как это сделать? Есть стандартные функции или нужно ловить событие нажатия на заголовок и писать свою функцию сортировки? Может есть у кого пример кода?

Автор: kometa_triatlon 2.6.2005, 04:57
Кое-что нашел в rsdn... Но остается два вопроса. Как узнать, на хидер какого столбца нажали? И как вывести треугольник?

Автор: Lion 2.6.2005, 09:13
Вкратце:
1. Обрабатывается сообщение LVN_COLUMNCLICK списка. Там приходит структура, в которой есть индекс столбца.
2. Значок рисуешь сам , подставляя изображение с прозрачным фоном в CHeaderCtrl списка.
3. Еще надо написать CALLBACK функции сравнения строк списка.

Код есть, но он в проекте. Пример могу написать, к вечеру. Если сильно надо, обращайтесь. smile

Автор: kometa_triatlon 2.6.2005, 12:30
Сильно надо!!! Первый раз работаю с CListCtrl, нужен пример.
Ну план понятен, но реализовать я его не смогу smile
Цитата
. Обрабатывается сообщение LVN_COLUMNCLICK списка. Там приходит структура, в которой есть индекс столбца

Название поля узнаю методом тыка smile
Цитата
Значок рисуешь сам , привязывая список изображений с прозрачным фоном к CHeaderCtrl списка и устанавливая соответствующий значок.

А вот здесь не понял. Точнее понял, но не знаю как сделать...

Автор: Lion 2.6.2005, 14:07
Завтра с утра.

Автор: kometa_triatlon 2.6.2005, 23:45
smile
Завтра с утра я уже сдам прогу...
Ну все равно, хоть научусь.

Автор: St. Andrew 3.6.2005, 01:39
kometa_triatlon, а можешь примерчик выложить? А то мы сегодня полдня пытались заставить работать CListCtrl и ничего в него толком не вывелось... smile Примерчик будет очень и очень кстати! smile Если нетрудно, можешь на мыло бросить программку?

Автор: Lion 3.6.2005, 06:25
Цитата(kometa_triatlon @ 2.6.2005, 20:45)
smile
Завтра с утра я уже сдам прогу...
Ну все равно, хоть научусь.

Ну блин Семен Семеныч, где ж ты раньше был.smile Сказал бы что надо к такому-то. Я бы вчера еще написал. smile


Файл прилагаю. Там в общем не все так просто. smile

P.S. Код сильно не пинать.

Автор: kometa_triatlon 3.6.2005, 06:47
St. Andrew
Нетрудно smile


Lion
Ну ты все равно успел smile, сейчас буду дуплить smile

Автор: Lion 3.6.2005, 06:49
Цитата(kometa_triatlon @ 3.6.2005, 03:47)
Lion
Ну ты все равно успел smile, сейчас буду дуплить smile

Буду следить за форумом, если что не понятно пиши (можешь прям с кусками кода).

Автор: kometa_triatlon 3.6.2005, 06:59
Мыло только что отправил, пример посмотрел, понравилось smile
Всем спасибо smile

Автор: St. Andrew 3.6.2005, 16:07
kometa_triatlon, Большое спасибо! smile

Автор: kometa_triatlon 4.6.2005, 23:11
Самое грустное, это то, что у меня это код не заработал smile
Пример работает нормально, но как только перенес код, сортировка кончилась smile
Следствие показало, что проблема здесь:
Код

str1=pView->m_listList.GetItemText(nIndex, 0);
    // Вторая строка
    FindInfo.lParam=lParam2;
    nIndex=nIndex=pView->m_listList.FindItem(&FindInfo);
    
    str2=pView->m_listList.GetItemText(nIndex, 0);

Обе строки принимают одно значение (если конкретнее - текст первого элемента списка)
Не понимаю... smile
Код

.....
typedef struct tagStructInfoType
{
    UINT    nCol;
    UINT    nCode;
} StructInfoType;

#define    SORT_ASC    0
#define    SORT_DESC    1

......


void Clab8View::OnColumnclickList(NMHDR* pNMHDR, LRESULT* pResult)
{
    LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    *pResult = 0;

    CHeaderCtrl    *pHdr=m_listList.GetHeaderCtrl();
    HDITEM    HdrItem;
    HdrItem.mask=HDI_FORMAT;
    HdrItem.fmt=HDF_STRING;
    
    pHdr->SetItem(m_SortInfo.nCol, &HdrItem);
    
    if(m_SortInfo.nCol!=(UINT)pNMLV ->iSubItem)
    {
        m_SortInfo.nCol=(UINT)pNMLV ->iSubItem;
        m_SortInfo.nCode=SORT_ASC;
        Sort();
        return;
    }
    else
    {
        if(m_SortInfo.nCode==SORT_ASC)
        {
            m_SortInfo.nCode=SORT_DESC;
            Sort();
            return;
        }
        if(m_SortInfo.nCode==SORT_DESC)
        {
            m_SortInfo.nCode=SORT_ASC;
            Sort();
            return;
        }
    }
}

void Clab8View::Sort(void)
{

    CWaitCursor    Wait;
    // Заголовок
    CHeaderCtrl    *pHdr=m_listList.GetHeaderCtrl();
    HDITEM    HdrItem;
    HdrItem.mask=HDI_BITMAP|HDI_FORMAT;
    HdrItem.fmt=HDF_STRING|HDF_BITMAP|HDF_BITMAP_ON_RIGHT;
    if(m_SortInfo.nCode==SORT_ASC)
    {
        HdrItem.hbm=m_bmpSortUpArrow;
    }
    else
    {
        HdrItem.hbm=m_bmpSortDownArrow;
    }
    
        // Сортировка по строке
        m_listList.SortItems(SortStr, (LPARAM)this);
        HdrItem.fmt|=HDF_LEFT;
    

    pHdr->SetItem(m_SortInfo.nCol, &HdrItem);
}

int CALLBACK Clab8View::SortStr(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
    CString    str1, str2;
    LVFINDINFO    FindInfo;
    memset(&FindInfo, 0, sizeof(LVFINDINFO));
    FindInfo.flags=LVFI_PARAM;
    // Первая строка
    FindInfo.lParam=lParam1;
    Clab8View* pView = (Clab8View*)lParamSort;
    int    nIndex=pView->m_listList.FindItem(&FindInfo);
    //int num = pView->m_SortInfo.
    str1=pView->m_listList.GetItemText(nIndex, 0);
    // Вторая строка
    FindInfo.lParam=lParam2;
    nIndex=nIndex=pView->m_listList.FindItem(&FindInfo);
    
    str2=pView->m_listList.GetItemText(nIndex, 0);
    // Сравниваем строки
    TRACE(str1);
    TRACE(str2);
    if(pView->m_SortInfo.nCode==SORT_ASC)
    {
        return strcmp(str1, str2);
    }
    if(pView->m_SortInfo.nCode==SORT_DESC)
    {
        return (-1*strcmp(str1, str2));
    }
    return 0;
    
}

Автор: Lion 6.6.2005, 04:55
Сори был в offline.

Ты при заполнении списка делаешь SetItemData(…)? Если нет, то у тебя для всех Item в функцию сортировки приходят нули, автоматически подставленные при добавлении Item-ов. smile Нужно каждому Item сопоставить функцией SetItemData(…) уникальный индекс, чтобы ты мог его потом найти в функции сортировки.

Посмотри функцию FillList() в примере.



Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)