У меня есть подкласс CMFCListCtrl, который поддерживает сортировку, чтение документации я должен реализовать виртуальный метод:Странное поведение при сортировке CMFCListCtrl
virtual int OnCompareItems(LPARAM lParam1, LPARAM lParam2, int nColumn);
где lParam1 и lParam2 являются PARAMS некоторого вида, указанный при создании элемента управления списком.
Поскольку мне нужно алфавитный то я вставил свои строки таким образом:
item.mask = LVIF_COLFMT | LVIF_IMAGE | LVIF_PARAM | LVIF_TEXT;
for (nI = 0; nI ....)
{
// UMASK, ITEM IDX, TEXT, STATE 1, STATE 2, IMAGE IDX, LPARAM
m_lstMateriali.InsertItem(item.mask, nI, _T(" "), 0, 0, SelezionaIcona(itIM->m_bSelez, itIM->m_eStatus), nI);
strQnt.Format(_T("%d"), itIM->m_nIdBolla);
m_lstMateriali.SetItemText(nI, 1, strQnt);
m_lstMateriali.SetItemText(nI, 2, itIM->m_strCodMater);
m_lstMateriali.SetItemText(nI, 3, itIM->m_strDescrMater);
m_lstMateriali.SetItemText(nI, 4, itIM->m_strColore);
strQnt.Format(_T("%d"), itIM->m_nDaTag);
m_lstMateriali.SetItemText(nI, 5, strQnt);
m_lstMateriali.SetItemData(nI, nI);
}
На данный момент, мой Подкласс метод сортировки:
virtual int OnCompareItems(LPARAM lParam1, LPARAM lParam2, int nColumn)
{
int nCol_1; ///<
int nCol_2; ///<
CString strCol_1; ///<
CString strCol_2; ///<
strCol_1 = GetItemText(lParam1, nColumn);
strCol_2 = GetItemText(lParam2, nColumn);
switch (nColumn)
{
case 2:
return strCol_1.Compare(strCol_2);
}
}
сильно работает. Но теперь, из-за сортировки, мои LPARAM не являются более правильными, так как они представляют номер строки. Затем я обработал уведомление заголовка щелчка, которое происходит после сортировки:
void CEliCUTK2SceltaMaterialiDlg::OnHdnItemclickLstSmListapezzi(NMHDR * pNMHDR, LRESULT * pResult)
{
int nNumRig;
CString strCodMat;
LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
LVITEM item;
nNumRig = m_lstMateriali.GetItemCount();
memset(&item, 0, sizeof(LVITEM));
item.mask = LVIF_PARAM;
for (int nI = 0; nI < nNumRig; nI++)
{
item.iItem = nI;
item.lParam = nI;
m_lstMateriali.SetItem(&item); // (1)
strCodMat = m_lstMateriali.GetItemText(nI, 2);
// bla bla about item data
}
*pResult = 0;
}
это может быть наихудшей практика, но сейчас он работает довольно хорошо: я поставил новую LPARAMs в соответствии с новой строки номера. Я также взял текст до и после пункта (1), чтобы проверить, обновил ли я правильную строку , и все кажется прекрасным: сначала я получил старый параметр param и первый параметр.
Что теперь: я щелкнул еще раз в заголовке строки, чтобы сортировать нисходящий и что я получаю? Все скривилось. я решил проверить некоторые вещи, и я добавил следующий код:
void CEliCUTK2SceltaMaterialiDlg::OnLvnItemchangedLstSmListapezzi(NMHDR * pNMHDR, LRESULT * pResult)
{
int nSot, nTip;
CString strID;
DWORD_PTR dwID;
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
LVITEM item;
if (pNMLV->uNewState == 3)
{
dwID = m_lstMateriali.GetItemData(pNMLV->iItem);
memset(&item, 0, sizeof(LVITEM));
item.mask = LVIF_PARAM;
item.iItem = pNMLV->iItem;
m_lstMateriali.GetItem(&item);
strID.Format(_T("PARAM: %ld."), item.lParam);
AfxMessageBox(strID);
}
*pResult = 0;
}
перезапустил программу сортировки списка снова и нажав первую строки (после проверки еще раз, что новая LPARAMs правильно) I получил сообщение:
PARAM: 10.
в то время как я должен получить:
PARAM: 0.
10 - старая позиция. Есть что-то, чего я где-то не хватает?
Ну, это то, что я сделал в другом классе, подобном этому. В любом случае: вы говорите мне, что, как только я установлю lParam, нет способа изменить его, если я не удалю элемент и не верну его обратно? – IssamTP
Вы можете изменить его и сделать все, что захотите. Однако я не думаю, что вы должны его изменить. Я думаю, что вы должны установить его один раз и как-то ссылаться на исходные данные, а затем в вашей функции сравнения использовать lParam для ссылки на исходные данные, а затем вернуть значение, основанное на сравнении с исходными данными. –
Хорошо, вот и все, но потом, если я могу изменить его (лучшая или худшая практика, я не против), почему я получил ее сброс до 10, если я установил ее в 0? – IssamTP