我扩展了CMFCListCtrl
类,主要是为了能够轻松按列排序。从我学到的知识来看,实现Sort
和OnCompareItems
运行功能就足够了。
发生的情况是,该排序对于类型为的第一列工作正常,integer
但是对于类型为的第二列却给出了奇怪的排序string
。没有错误,顺序已更改,但不按字母顺序。
int MyCMFCListCtrl::OnCompareItems(LPARAM lParam1, LPARAM lParam2, int iColumn)
{
if (iColumn == 0)
{
if (lParam1 > lParam2)
return -1;
else if (lParam1 < lParam2)
return 1;
else
return 0;
}
else if (iColumn == 1)
{
CString strCol1, strCol2;
strCol1 = GetItemText(lParam1, iColumn);
strCol2 = GetItemText(lParam2, iColumn);
return strCol1.Compare(strCol2);
}
return 0;
}
void MyCMFCListCtrl::Sort(int iColumn, BOOL bAscending, BOOL bAdd)
{
// Sort available for first and second column
if (iColumn > 1) return;
CMFCListCtrl::Sort(iColumn, bAscending, bAdd);
}
我输入的值OnCompareItems
对于两列都是可以的。但是最终结果仅对第一个有效。要使此功能正常工作,还需要其他功能吗?
CMFCListCtrl::Sort
会打电话给CListCtrl::SortItems
。SortItems
会将LPARAM
项目数据传递给回调函数。这LPARAM
是可以用设置的值SetItemData
。
这意味着lParam1
和lParam2
中的OnCompareItems
,LPARAM
仅指数据。
GetItemText(lParam1, iColumn)
在这种情况下是未定义的行为,因为lParam1
它不引用行号。
另请参见LVM_SORTITEMS
和的文档LVM_SORTITEMSEX
Sort
并致电 SortItemsEx
。这样 lParam1
, lParam2
将引用行号,并且 GetItemText(lParam1, iColumn)
将是有效的调用,如下所示。请注意, (iColumn == 0)
仅在 SetItemData
更早调用时才使用条件 。
int MyCMFCListCtrl::OnCompareItems(LPARAM lParam1, LPARAM lParam2, int iColumn)
{
if(iColumn == 0)//assuming SetItemData was called earlier
return lParam1 - lParam2;
CString strCol1 = GetItemText(lParam1, iColumn);
CString strCol2 = GetItemText(lParam2, iColumn);
return strCol1.Compare(strCol2);
}
void MyCMFCListCtrl::Sort(int iColumn, BOOL bAscending, BOOL bAdd)
{
if(iColumn == 0)//assuming SetItemData was called earlier
{
//call SortItem and get LPARAM data in call back function
CMFCListCtrl::Sort(iColumn, bAscending, bAdd);
return;
}
//call SortItemEx instead, get row numbers in callback function
CWaitCursor wait;
GetHeaderCtrl().SetSortColumn(iColumn, bAscending, bAdd);
m_iSortedColumn = iColumn;
m_bAscending = bAscending;
SortItemsEx(CompareProc, (LPARAM)this);
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句