Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.118.200.86] |
|
Сообщ.
#1
,
|
|
|
Подскажите, как сделать свою сортировку в CListCtrl? Не устраивает стандартная сортировка числовой части строк.
Как нужно правильно в функции сравнения преобразовать LPARAM в CString? |
Сообщ.
#2
,
|
|
|
CListCtrl, как пользоваться?
Здесь выкладывал пример кода сортировки по датам, по строкам, по числам и суммам. И соответственно иконкой направления сортировки в заголовке колонки. |
Сообщ.
#3
,
|
|
|
Почему у меня получается так, что в функцию сравнения приходят lParam1 и lParam2, всегда равные нулю?
|
Сообщ.
#4
,
|
|
|
Покажи код.
|
Сообщ.
#5
,
|
|
|
CListCtrl::SortItems((PFNLVCOMPARE) CompareFunc, 0); int CALLBACK CMyListCtrl::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { int i; CString str, str2; LVFINDINFO ItemInfo; ItemInfo.flags = LVFI_PARAM; ItemInfo.lParam = lParam1; i = m_pThis->FindItem(&ItemInfo); str = m_pThis->GetItemText(i, 0); ItemInfo.lParam = lParam2; i = m_pThis->FindItem(&ItemInfo); str2 = m_pThis->GetItemText(i, 0); return MyCompare(str, str2); } |
Сообщ.
#6
,
|
|
|
При заполнении ListCtrl ты используешь SetItemData(...)?
MSDN: Цитата The function SetItemData is called, passing the new ITEMDATA as a parameter. This reinitializes the lParam of the item's LVITEM structure, and prepares the way for the sort. Почитай здесь. |
Сообщ.
#7
,
|
|
|
SetItemData() не использовал. Не думал, что такие навороты...
В примере по ссылке весь список хранится еще раз в массиве. Не нравиться мне это. Проще нельзя? Для моего случая с FindItem() что нужно указать в SetItemData() ? |
Сообщ.
#8
,
|
|
|
У меня первый и второй параметры были равны индексу строки; второй параметр должен быть уникальным для каждой строки, т.е. он нигде не должен повторяться.
|
Сообщ.
#9
,
|
|
|
Guest
Возьми зарегистрируйся, появиться возможность приаттачивать архив проекта проги. Прицепи проект, люди посмотрят и вернут исправленный с комментариями. Все быстрее решиться. |
Сообщ.
#10
,
|
|
|
AViK
Не понятно. Если можно, покажи в коде. IEZ Проект большой, придется списочную часть выделять в отдельный проект - а не охота. Проблема-то только в том, что указать в SetItemData()... |
Сообщ.
#11
,
|
|
|
Цитата Guest @ Проблема-то только в том, что указать в SetItemData()... В примере по ссылке, можно и так и так. |
Сообщ.
#12
,
|
|
|
Посмотри эти файлы
Прикреплённый файлSortListView.rar (8.99 Кбайт, скачиваний: 255) |
Сообщ.
#13
,
|
|
|
Я делал так:
int iRecCount=0; while(!pRst->adoEOF) { ... index=list.InsertItem(count++,sData,0); list.SetItemText(index,1,sPost); list.SetItemText(index,2,sNaim); list.SetItemText(index,3,sMark); list.SetItemText(index,4,sSerial); list.SetItemText(index,5,sBrak); list.SetItemText(index,6,sOtprav); list.SetItemData(index,iRecCount++); ... } |
Сообщ.
#14
,
|
|
|
Помогите плиз. У меня не получается сортировка в CListCtrl. Я данные вытягиваю через запросы SQL с БД. заношу их вот так:
rs.Open(dbOpenDynaset, "SELECT [Students List].FIO, [Group Names List].Group, [Post Names List].Exam, [Job Names List].Exam FROM [Students List], [Group Names List], [Post Names List], [Job Names List] WHERE [Students List].CodeGroup = [Group Names List].CodeGroup AND [Post Names List].CodeExam = [Students List].CodePost AND [Job Names List].CodeExam=[Students List].CodeJob"); while (!rs.IsEOF()) { val = rs.GetFieldValue(0); str = CCrack::strVARIANT(val); valu = rs.GetFieldValue(1); stor = CCrack::strVARIANT(valu); dol = rs.GetFieldValue(2); sol = CCrack::strVARIANT(dol); kol = rs.GetFieldValue(3); lol = CCrack::strVARIANT(kol); int nItem = m_ListItems.Add(MyListItem(str, stor, sol, lol)); int nIndex = list1.InsertItem(list.GetItemCount(), ""); list1.SetItemText(nIndex, 0, str); list1.SetItemText(nIndex, 1, stor); list1.SetItemText(nIndex, 2, sol); list1.SetItemText(nIndex, 3, lol); list1.SetItemData(nIndex, i); list1.SetItemData(nIndex, (LPARAM)& m_ListItems[nItem]); i++; rs.MoveNext(); } А callback пишу так: int CALLBACK CDllprobaApp::MyCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { int nCol = (int) lParamSort; MyListItem* item1 = (MyListItem*)lParam1; MyListItem* item2 = (MyListItem*)lParam2; switch(nCol) { case 0: return strcmp(item1->getName(), item2->getName()); break; case 1: return strcmp(item1->getGroup(), item2->getGroup()); break; case 2: return strcmp(item1->getDolzhn(), item2->getDolzhn()); break; case 3: return strcmp(item1->getMesto(), item2->getMesto()); break; default: return strcmp(item1->getName(), item2->getName()); break; } } Ошибок нет, но при нажатии на любую колонку он материться и прога вылетает. Что я не так делаю. Может что-то с массивом в который я заношу данные для сортировки. |
Сообщ.
#15
,
|
|
|
Во втором посте данной темы есть ссылка, где выкладывается код сортировки.
Вот кусок кода: Цитата static int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { int iInex; LVFINDINFO ItemInfo; _int64 m_iNum1=0; _int64 m_iNum2=0; SYSTEMTIME m_stDate1; SYSTEMTIME m_stDate2; FILETIME m_ftPeriod1; FILETIME m_ftPeriod2; LARGE_INTEGER m_liPeriod1; LARGE_INTEGER m_liPeriod2; CString m_sText1; CString m_sText2; double m_dSum1=0; double m_dSum2=0; unsigned int m_uiSort=SORT_NORMAL; ItemInfo.flags=LVFI_PARAM; ItemInfo.lParam=lParam1; iInex=m_wndListCtrl.FindItem(&ItemInfo); m_sText1=m_wndListCtrl.GetItemText(iInex, (int)lParamSort); ItemInfo.lParam=lParam2; iInex=m_wndListCtrl.FindItem(&ItemInfo); m_sText2=m_wndListCtrl.GetItemText(iInex, (int)lParamSort); switch(lParamSort) { case 0: m_uiSort=SORT_NUMBER; break; case 4: case 8: m_uiSort=SORT_DATE; break; case 1: case 2: case 3: case 5: case 6: case 7: case 9: m_uiSort=SORT_STRING; break; } switch(m_uiSort) { case SORT_NORMAL: break; case SORT_NUMBER: m_iNum1=atoi(m_sText1); m_iNum2=atoi(m_sText2); if(bAscending==true) { iReturn=(INT)(m_iNum1-m_iNum2); } else { iReturn=(INT)(m_iNum2-m_iNum1); } break; case SORT_DATE: SetStringToDateTime(m_sText1, NULL, &m_stDate1); SetStringToDateTime(m_sText2, NULL, &m_stDate2); SystemTimeToFileTime(&m_stDate1, &m_ftPeriod1); SystemTimeToFileTime(&m_stDate2, &m_ftPeriod2); memcpy(&m_liPeriod1, &m_ftPeriod1, sizeof(FILETIME)); memcpy(&m_liPeriod2, &m_ftPeriod2, sizeof(FILETIME)); if(m_liPeriod1.QuadPart<m_liPeriod2.QuadPart) { if(bAscending==true) { iReturn=-1; } else { iReturn=1; } } else if(m_liPeriod1.QuadPart==m_liPeriod2.QuadPart) { iReturn=0; } else if(m_liPeriod1.QuadPart>m_liPeriod2.QuadPart) { if(bAscending==true) { iReturn=1; } else { iReturn=-1; } } break; case SORT_STRING: if(bAscending==true) { iReturn=strcmp(m_sText1, m_sText2); } else { iReturn=strcmp(m_sText2, m_sText1); } break; case SORT_SUM: m_dSum1=atof(m_sText1); m_dSum2=atof(m_sText2); if(m_dSum1<m_dSum2) { if(bAscending==true) { iReturn=-1; } else { iReturn=1; } } else if(m_dSum1==m_dSum2) { iReturn=0; } else if(m_dSum1>m_dSum2) { if(bAscending==true) { iReturn=1; } else { iReturn=-1; } } break; } return iReturn; } Обрати внимание на выделенные текст. И что ты делаешь здесь? MyListItem* item1 = (MyListItem*)lParam1; MyListItem* item2 = (MyListItem*)lParam2; А вот здесь у тебя что-нибудь сравнивается? Я имею ввиду текст, проверял. strcmp(item1->getName(), item2->getName()); |
Сообщ.
#16
,
|
|
|
Вот именно, что он даже не заносит в массив ничего и естественно ничего не сравнивает. Хотя по теории он должен всё заносить.
А когда я ставлю функцию как static он мне материться: MyCompareFunc' : 'static' should not be used on member functions defined at file scope |
Сообщ.
#17
,
|
|
|
Ну правильно по lParam ты должен найти номер строки в CListCtrl:
ItemInfo.lParam=lParam1; iInex=m_wndListCtrl.FindItem(&ItemInfo); А уж зная номер строки, получаешь текст для сравнения: m_sText1=m_wndListCtrl.GetItemText(iInex, (int)lParamSort); Это сделано для первого из сравневаемых параметров, соответственно подобное нужно сделать и для второго. А уж потом сравнивать. Если есть возможность прицепить проект, выкладывай, быстрее будет найдена ошибка. |
Сообщ.
#18
,
|
|
|
IEZ, извините может я, что - то не понимаю, но как же в MyCompareProc будет виден CListBox? Попытался повторить ваш код и сталкнулся с такой проблемой? Если не трудно объясните пожалуйста
|
Сообщ.
#19
,
|
|
|
Граждане, я пробовал применить этот код, но при условии, к примеру, первые несколько значений идентичны и находятся вверху, данный код постоянно берет индекс "0" и сравнивает только с самим собой и соответственно ничего не сортирует...
|