Re: CListCtrl sort not working
"Bill Brehm >" <<don't want spam> wrote in message
news:Okd%23PDpoIHA.5916@TK2MSFTNGP04.phx.gbl...
I had seen that article but I read throuugh it so fast I missed the key
point. I can understand how it works but I have two problems with it.
1. It is basically keeping two copies of every piece of data. One is in
strData and the other in the CListCtrl itself. And of course, there is
also the m_pData array that links the CListCtrl to strData. The
documentation implies that I can maintain the data myself and set a
callback to provide the data needed to the list ctrl on demand. It's not
very thorough at showing how to do that. I've gotten as far as learing
that I have to handle message LVN_GETDISPINFO. But I can't find anywhere
an example of how to return the information requested. Is there any
description of how to do this?
I can share with you how I did it for one of my programs. In a nutshell,
when you add items to the list, instead of specifying the string to display,
you specify LPSTR_TEXTCALLBACK, e.g.
m_lcPortfolio.InsertItem (i, LPSTR_TEXTCALLBACK);
This causes LVN_GETDISPINFO to be called requesting the text to display,
e.g.
void CPageStock::OnGetdispinfoListPortfolio(NMHDR* pNMHDR, LRESULT* pResult)
{
// The data to display is stored in a CArray. Items in the array are
accessed by
// CAppData::GetStockRecord(int index).
// The index of the item that Windows is asking for is
pDispInfo->item.iItem. But the data stored
// in this row of the list control can be different, if the list is
sorted. The CArray index of the item
// in the currently sorted order is stored in the item data. Therefore,
the CArray index is gotten by
// m_lcPortfolio.GetItemData(pDispInfo->item.iItem).
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
CStockRecord *pStockRec = CAppData::GetStockRecord
(m_lcPortfolio.GetItemData(pDispInfo->item.iItem));
// Assuming the list control is in Report mode, must display different
strings for the desired column.
// The column being asked for is pDispInfo->item.iSubItem.
switch (pDispInfo->item.iSubItem)
{
case 0:
pDispInfo->item.pszText = (LPSTR) pStockRec->GetName();
break;
case 1:
{
pDispInfo->item.pszText = (LPSTR)pStockRec->GetCost();
break;
}
}
}
2. This example assumes that the pointer to the data will remain valid
because the data won't move. My data is coming from the file and folder
heirarchy of the hard drive and I am storing it in a CArray. If the CArray
needs to grow it may reallocate space and copy the data to th e new space,
meaning all the pointers will point to nothing. Under this circumstance do
I have to do the sort by myself and not use the SortItems function at all
and basically empty the list control and refill it to do a sort?
The item data in the list control should not have pointers. It should have
indexes into the CArray. Sorting the list changes the indexes stored in the
item data. So since the list control never contains any pointers, this is
not a concern.
Hope this helps.
-- David