From: "Bill Brehm" don't want on
I have a CListCtrl. In response to pressing one of the columns, I process
the LVN_COLUMNCLICK notification by calling SortItems() and providing a
callback. The two parameters coming to my callback function are always zero.
The documentation implies that the two parameters are indexes of two rows to
be compared. I did a search and found this FAQ
http://www.celticwolf.com/FAQs/CListCtrl_FAQ.html#Q14 that says those
parameters are really the 32 bit data item stored in the row item. I
confirmed this. Unfortunately the FAQ doesn't suggest how this should be
used. I did try to set the data item equal to the index of the row item and
the first sort works. Problem is, a subsequent sort doesn't work because now
the data item no longer matches the actual index of the row item. I suppose
I could change the data items depending on whether I pass back a positive,
zero or negative value, but it seems to me I shouldn't have to do that and
also, it seems to me that the data item loses it's usefulness if I just have
to store an index in it.

So how is a sort meant to work?

Thanks...


From: Tom Serface on
This article should help you:

http://support.microsoft.com/kb/250614

Tom

"Bill Brehm >" <<don't want spam> wrote in message
news:eProxrioIHA.548(a)TK2MSFTNGP06.phx.gbl...
>I have a CListCtrl. In response to pressing one of the columns, I process
>the LVN_COLUMNCLICK notification by calling SortItems() and providing a
>callback. The two parameters coming to my callback function are always
>zero. The documentation implies that the two parameters are indexes of two
>rows to be compared. I did a search and found this FAQ
>http://www.celticwolf.com/FAQs/CListCtrl_FAQ.html#Q14 that says those
>parameters are really the 32 bit data item stored in the row item. I
>confirmed this. Unfortunately the FAQ doesn't suggest how this should be
>used. I did try to set the data item equal to the index of the row item and
>the first sort works. Problem is, a subsequent sort doesn't work because
>now the data item no longer matches the actual index of the row item. I
>suppose I could change the data items depending on whether I pass back a
>positive, zero or negative value, but it seems to me I shouldn't have to do
>that and also, it seems to me that the data item loses it's usefulness if I
>just have to store an index in it.
>
> So how is a sort meant to work?
>
> Thanks...
>

From: Giovanni Dicanio on

"Tom Serface" <tom.nospam(a)camaswood.com> ha scritto nel messaggio
news:DC7E5B5D-BD6F-4AE2-B396-D70EC982C617(a)microsoft.com...
> This article should help you:
>
> http://support.microsoft.com/kb/250614

The article pointed by Tom is of course a good start.

However, it has some problems, IMHO.

For example:

The comparing function SortFunc in the aforementioned article uses the
obsolete strcmp function to compare strings.
I don't like this way of comparing strings.

I believe that it fails in Unicode builds, where LPTSTR expands to wchar_t*.
The author of the article should have used _tcscmp for coherence with
Unicode builds.

Moreover, I don't like the fact that the author of the article uses raw
TCHAR* pointers for string. I believe that using a robust class for strings
like CString is a better choice.

I also don't like the fact that in the article a raw C-style vector of
pointers is used to store the custom data for each list item. I do prefer
using STL std::vector as a container, instead of a fixed-size raw C-style
array storing pointers.

Moreover, in the OnItemclickList1 handler associated to HDN_ITEMCLICK, the
author casts to NMLISTVIEW*, but I would instead prefer to cast to
NMHEADER*, as from MSDN documentation for HDN_ITEMCLICK:

HDN_ITEMCLICK Notification

http://msdn2.microsoft.com/en-us/library/bb775286(VS.85).aspx

// Author's code - IMHO, bad:
NMLISTVIEW *pLV = (NMLISTVIEW *) pNMHDR;

// Better code casting to NMHEADER*
LPNMHEADER phdr = reinterpret_cast< LPNMHEADER >( pNMHDR );

I wrote a demo app to show sorting of list controls, using the corrections I
pointed here.
I used Visual C++ 9 (VS2008).

The VC9 solution can be downloaded here, with source code:
http://www.geocities.com/giovanni.dicanio/vc/TestSortListCtrl.zip

Here's a screenshot:
http://www.geocities.com/giovanni.dicanio/vc/TestSortListCtrl.jpg

HTH,
Giovanni




From: "Bill Brehm" don't want on
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?

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?

Thanks...



"Tom Serface" <tom.nospam(a)camaswood.com> wrote in message
news:DC7E5B5D-BD6F-4AE2-B396-D70EC982C617(a)microsoft.com...
> This article should help you:
>
> http://support.microsoft.com/kb/250614
>
> Tom
>
> "Bill Brehm >" <<don't want spam> wrote in message
> news:eProxrioIHA.548(a)TK2MSFTNGP06.phx.gbl...
>>I have a CListCtrl. In response to pressing one of the columns, I process
>>the LVN_COLUMNCLICK notification by calling SortItems() and providing a
>>callback. The two parameters coming to my callback function are always
>>zero. The documentation implies that the two parameters are indexes of two
>>rows to be compared. I did a search and found this FAQ
>>http://www.celticwolf.com/FAQs/CListCtrl_FAQ.html#Q14 that says those
>>parameters are really the 32 bit data item stored in the row item. I
>>confirmed this. Unfortunately the FAQ doesn't suggest how this should be
>>used. I did try to set the data item equal to the index of the row item
>>and the first sort works. Problem is, a subsequent sort doesn't work
>>because now the data item no longer matches the actual index of the row
>>item. I suppose I could change the data items depending on whether I pass
>>back a positive, zero or negative value, but it seems to me I shouldn't
>>have to do that and also, it seems to me that the data item loses it's
>>usefulness if I just have to store an index in it.
>>
>> So how is a sort meant to work?
>>
>> Thanks...
>>
>


From: David Ching on

"Bill Brehm >" <<don't want spam> wrote in message
news:Okd%23PDpoIHA.5916(a)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


 |  Next  |  Last
Pages: 1 2
Prev: Can't get OLE interface
Next: Problem with MFC on Vista