// ListCtrlSortClass.cpp: implementation of the CListCtrlSortClass class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ListCtrlSortClass.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CListCtrlSortClass::CListCtrlSortClass(CListCtrl *pList, const int nCol) { m_pList = pList; ASSERT(m_pList); int totItems = m_pList->GetItemCount(); // Replace All Item Data with pointer to CSortItem class for (int i = 0; i < totItems; i++) { DWORD dw = m_pList->GetItemData(i); CString txt = m_pList->GetItemText(i, nCol); m_pList->SetItemData(i, (DWORD) new CSortItem(dw, txt)); } } CListCtrlSortClass::~CListCtrlSortClass() { // Reset Data value for All item and delete CSortItem pointer ASSERT(m_pList); int totItems = m_pList->GetItemCount(); for (int i = 0; i < totItems; i++) { CSortItem *pItem = (CSortItem*)(m_pList->GetItemData(i)); ASSERT(pItem); m_pList->SetItemData(i, pItem->m_dw); delete pItem; } } void CListCtrlSortClass::Sort(BOOL bAsc, SortDataType dtType) { // Prepare lParamSort: value == dtType, // with sign positive for ascending sort order, negative - descending long lParamSort = bAsc ? dtType : -dtType; m_pList->SortItems(Compare, lParamSort); } int CALLBACK CListCtrlSortClass::Compare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { CSortItem *pItem1 = (CSortItem*)lParam1; CSortItem *pItem2 = (CSortItem*)lParam2; ASSERT(pItem1 && pItem2); int nOrder = (lParamSort < 0) ? -1 : 1; SortDataType dtType = (SortDataType) (lParamSort * nOrder); // get rid of sign switch (dtType) { case SortDataType::dtINT: return (_ttol(pItem1->m_txt) - _ttol(pItem2->m_txt)) * nOrder; case SortDataType::dtFLOAT: return (int) ((_tstof(pItem1->m_txt) - _tstof(pItem2->m_txt)) * nOrder); case SortDataType::dtDEC: return (int) ((_tstof(pItem1->m_txt) - _tstof(pItem2->m_txt)) * nOrder); case SortDataType::dtSTRING: return pItem1->m_txt.Compare(pItem2->m_txt) * nOrder; case SortDataType::dtSTRINGNOCASE: return pItem1->m_txt.CompareNoCase(pItem2->m_txt) * nOrder; case SortDataType::dtDATETIME: { COleDateTime time1, time2; if (time1.ParseDateTime(pItem1->m_txt) && time2.ParseDateTime(pItem2->m_txt)) return ((time1 == time2) ? 0 : (time1 < time2 ? -1 : 1)) * nOrder; } default: ASSERT("Error: attempt to sort a column without type."); return 0; } }