|
#include "stdafx.h"
#include "CListCtrl_SortItems.h"
BEGIN_MESSAGE_MAP(CListCtrl_SortItems, CListCtrl)
ON_NOTIFY_REFLECT_EX(LVN_GETDISPINFO, OnGetDispInfo) // Text Callback
ON_NOTIFY_REFLECT_EX(LVN_COLUMNCLICK, OnHeaderClick) // Column Click
END_MESSAGE_MAP()
BOOL CListCtrl_SortItems::OnGetDispInfo(NMHDR* pNMHDR, LRESULT* pResult)
{
NMLVDISPINFO* pNMW = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
int nItem = pNMW->item.iItem;
int nSubItem = pNMW->item.iSubItem;
if (nItem< 0 || nItem >= GetItemCount())
return FALSE; // requesting invalid item
if (nSubItem < 0 || nSubItem >= GetHeaderCtrl()->GetItemCount())
return FALSE; // requesting invalid column
int col = GetColumnData(nSubItem);
size_t rowId = (size_t)GetItemData(nItem);
if(pNMW->item.mask & LVIF_TEXT)
{
// Request text
const string& result = m_DataModel.GetCellText(rowId, col);
_tcsncpy(pNMW->item.pszText, result.c_str(), pNMW->item.cchTextMax);
}
return FALSE; // Let parent-dialog get chance
}
namespace {
struct PARAMSORT
{
PARAMSORT(const CListCtrl_DataModel& datamodel, int columnData, bool ascending)
:m_DataModel(datamodel)
,m_ColumnData(columnData)
,m_Ascending(ascending)
{}
const CListCtrl_DataModel& m_DataModel;
int m_ColumnData;
bool m_Ascending;
};
// Comparison extracts values from the DataModel
int CALLBACK SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
PARAMSORT& ps = *(PARAMSORT*)lParamSort;
const string& left = ps.m_DataModel.GetCellText((size_t)lParam1, ps.m_ColumnData);
const string& right = ps.m_DataModel.GetCellText((size_t)lParam2, ps.m_ColumnData);
if (ps.m_Ascending)
return _tcscmp( left.c_str(), right.c_str() );
else
return _tcscmp( right.c_str(), left.c_str() );
}
}
bool CListCtrl_SortItems::SortColumn(int columnIndex, bool ascending)
{
if (GetItemCount()!=m_DataModel.GetRowIds())
return false;
int columnData = GetColumnData(columnIndex);
PARAMSORT paramsort(m_DataModel, columnData, ascending);
SortItems(SortFunc, (DWORD_PTR)¶msort);
return true;
}
void CListCtrl_SortItems::LoadData()
{
if (GetHeaderCtrl()->GetItemCount()==0)
{
// Create Columns
for(int col = 0; col < m_DataModel.GetColCount() ; ++col)
{
const string& title = m_DataModel.GetColTitle(col);
VERIFY( InsertColumn(col, title.c_str(), LVCFMT_LEFT, 100) != -1 );
}
}
else
{
// Empty list-control and force refresh
DeleteAllItems();
ResetSortOrder();
Invalidate();
UpdateWindow();
}
// Insert data with callback
SetRedraw(FALSE); // Disable redraw as InsertItem becomes so much faster
int nItem = 0;
for(size_t rowId = 0; rowId < m_DataModel.GetRowIds() ; ++rowId)
{
nItem = InsertItem(++nItem, ""); // Fastest to insert at the end
VERIFY(nItem!=-1);
VERIFY(SetItemData(nItem, rowId));
for(int col = 0; col < m_DataModel.GetColCount() ; ++col)
{
VERIFY(SetItemText(nItem, col, LPSTR_TEXTCALLBACK));
}
}
SetRedraw(TRUE);
Invalidate();
UpdateWindow();
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.