На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual C++ / MFC / WTL (далее Раздела)
1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Полезные ссылки:
user posted image FAQ Раздела user posted image Обновления для FAQ Раздела user posted image Поиск по Разделу user posted image MSDN Library Online
Модераторы: ElcnU
  
> Сортировка CListCtrl
    Подскажите, как сделать свою сортировку в CListCtrl? Не устраивает стандартная сортировка числовой части строк.
    Как нужно правильно в функции сравнения преобразовать LPARAM в CString?
      CListCtrl, как пользоваться?
      Здесь выкладывал пример кода сортировки по датам, по строкам, по числам и суммам. И соответственно
      иконкой направления сортировки в заголовке колонки.
        Почему у меня получается так, что в функцию сравнения приходят lParam1 и lParam2, всегда равные нулю?
          Покажи код.
            ExpandedWrap disabled
              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);
              }
              При заполнении 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.

              Почитай здесь.
                SetItemData() не использовал. Не думал, что такие навороты...
                В примере по ссылке весь список хранится еще раз в массиве. Не нравиться мне это. Проще нельзя? Для моего случая с FindItem() что нужно указать в SetItemData() ?
                  У меня первый и второй параметры были равны индексу строки; второй параметр должен быть уникальным для каждой строки, т.е. он нигде не должен повторяться.
                    Guest
                    Возьми зарегистрируйся, появиться возможность приаттачивать архив проекта проги.
                    Прицепи проект, люди посмотрят и вернут исправленный с комментариями.
                    Все быстрее решиться.
                      AViK
                      Не понятно. Если можно, покажи в коде.

                      IEZ
                      Проект большой, придется списочную часть выделять в отдельный проект - а не охота. Проблема-то только в том, что указать в SetItemData()...
                        Цитата Guest @
                        Проблема-то только в том, что указать в SetItemData()...

                        В примере по ссылке, можно и так и так.
                          Посмотри эти файлы
                          Прикреплённый файлПрикреплённый файлSortListView.rar (8.99 Кбайт, скачиваний: 255)
                            Я делал так:
                            ExpandedWrap disabled
                              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++);
                                    ...
                                    }
                              Помогите плиз. У меня не получается сортировка в 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;
                              }



                              }
                              Ошибок нет, но при нажатии на любую колонку он материться и прога вылетает. Что я не так делаю. Может что-то с массивом в который я заношу данные для сортировки.
                                Во втором посте данной темы есть ссылка, где выкладывается код сортировки.
                                Вот кусок кода:

                                Цитата
                                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;
                                }


                                Обрати внимание на выделенные текст.

                                И что ты делаешь здесь?

                                ExpandedWrap disabled
                                  MyListItem* item1 = (MyListItem*)lParam1;
                                  MyListItem* item2 = (MyListItem*)lParam2;


                                А вот здесь у тебя что-нибудь сравнивается? Я имею ввиду текст, проверял.
                                ExpandedWrap disabled
                                  strcmp(item1->getName(), item2->getName());
                                Сообщение отредактировано: IEZ -
                                  Вот именно, что он даже не заносит в массив ничего и естественно ничего не сравнивает. Хотя по теории он должен всё заносить.
                                  А когда я ставлю функцию как static он мне материться:
                                  MyCompareFunc' : 'static' should not be used on member functions defined at file scope
                                    Ну правильно по lParam ты должен найти номер строки в CListCtrl:
                                    ExpandedWrap disabled
                                      ItemInfo.lParam=lParam1;
                                      iInex=m_wndListCtrl.FindItem(&ItemInfo);

                                    А уж зная номер строки, получаешь текст для сравнения:
                                    ExpandedWrap disabled
                                      m_sText1=m_wndListCtrl.GetItemText(iInex, (int)lParamSort);

                                    Это сделано для первого из сравневаемых параметров, соответственно
                                    подобное нужно сделать и для второго.
                                    А уж потом сравнивать.

                                    Если есть возможность прицепить проект, выкладывай, быстрее будет найдена ошибка.
                                      IEZ, извините может я, что - то не понимаю, но как же в MyCompareProc будет виден CListBox? Попытался повторить ваш код и сталкнулся с такой проблемой? Если не трудно объясните пожалуйста
                                        Граждане, я пробовал применить этот код, но при условии, к примеру, первые несколько значений идентичны и находятся вверху, данный код постоянно берет индекс "0" и сравнивает только с самим собой и соответственно ничего не сортирует...
                                        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                        0 пользователей:


                                        Рейтинг@Mail.ru
                                        [ Script execution time: 0,0493 ]   [ 16 queries used ]   [ Generated: 1.05.24, 12:28 GMT ]