Prev: Can't get OLE interface
Next: Problem with MFC on Vista
From: "Bill Brehm" don't want on 19 Apr 2008 10:41 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 19 Apr 2008 11:38 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 19 Apr 2008 19:32 "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 19 Apr 2008 22:50 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 20 Apr 2008 02:56
"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 |