Sort columns by the image index of the column


This code was contributed by Mark Findlay.
// This is a simple modification of the text sorting routine by
// Zafir Anjum. (See "Sorting the list based on text in any column")

//
// It sorts the list based on the image index of the column being 
// sorted. You must only call this function when sorting a column
// that has an image associated with it.
//
// I added an additional helper function GetItemImageIndex() which
// simply returns the image index for the row and column specified.
// 

//////////////////////////////////////////////////////////
//**************************************************
// GetItemImageIndex
// return the image index of the selected row and col
int CMyListCtrl::GetItemImageIndex(int nRow, int nCol/*=0*)
{
    LV_ITEM lv = {0};
	lv.mask = LVIF_IMAGE;
	lv.iItem = nRow;
	lv.iSubItem = nCol;

	GetItem( &lv );

    return lv.iImage;
}


////////////////////////////////////////////////////////////////////
// Sort by image index of column
//
// This function is a simple modification of the text sorting function
// written by Zafir Anjum.
//
// SortInImageOrder	- Sort the list based on image index of column
// Returns		- Returns true for success
// nCol			- column that contains the text to be sorted
// bAscending	- indicate sort order
// nLow			- row to start scanning from - default row is 0
// nHigh		- row to end scan. -1 indicates last row
BOOL CMyListCtrl::SortInImageOrder(int nCol, BOOL bAscending, int nLow/*=0*, int nHigh/*=-1*)
{
    BOOL bRet = FALSE;

	if( nCol >= ((CHeaderCtrl*)GetDlgItem(0))->GetItemCount() )
		return FALSE;
	
	if( nHigh == -1 ) nHigh = GetItemCount() - 1;
	int nLo = nLow;   
	int nHi = nHigh;
	
	int nMidItem;
	
	if( nHi <= nLo ) 
        return FALSE;
	
	nMidItem = GetItemImageIndex( (nLo+nHi)/2, nCol );
	
	// loop through the list until indices cross
	while( nLo <= nHi )
	{
		// arrsRowText will hold all column text for one row
		CStringArray arrsRowText;
		
		// find the first element that is greater than or equal to 
		// the partition element starting from the left Index.
		if( bAscending )
			while( ( nLo < nHigh ) && (GetItemImageIndex(nLo, nCol) < nMidItem ) )
				++nLo;           
		else
			while( ( nLo < nHigh ) && (GetItemImageIndex(nLo, nCol) > nMidItem ) )
				++nLo;
                
		// find an element that is smaller than or equal to 
		// the partition element starting from the right Index.
		if( bAscending )
			while( ( nHi > nLow ) && (GetItemImageIndex(nHi, nCol) > nMidItem ) )
				--nHi;           
		else
			while( ( nHi > nLow ) && (GetItemImageIndex(nHi, nCol) < nMidItem ) )
				--nHi;
				
		// if the indexes have not crossed, swap                
		// and if the items are not equal
		if( nLo <= nHi )
		{
			// swap only if the items are not equal
			if(GetItemImageIndex(nLo, nCol) != GetItemImageIndex(nHi, nCol) )
			{                               
				// swap the rows
                LV_ITEM lvitemlo = {0};
                LV_ITEM lvitemhi = {0};
                
                // Get the column count
				int nColCount =
							((CHeaderCtrl*)GetDlgItem(0))->GetItemCount();
				arrsRowText.SetSize( nColCount );
                
                // Load string array with text items of Lo row
				int i;
				for( i=0; i < nColCount; i++)
							arrsRowText[i] = GetItemText(nLo, i);
                
                // Setup Lo item structure
				lvitemlo.mask = LVIF_IMAGE | LVIF_STATE;

                // lParam only avail on col zero
                if (nCol == 0)
                    lvitemlo.mask |= LVIF_PARAM;

				lvitemlo.iItem = nLo;
				lvitemlo.iSubItem = nCol; // 10/29/97 0;
				lvitemlo.stateMask = 
                        LVIS_CUT            | LVIS_DROPHILITED      |
						LVIS_FOCUSED        | LVIS_SELECTED         |
						LVIS_OVERLAYMASK    | LVIS_STATEIMAGEMASK;

                // duplicate to hi item except for iItem index
				lvitemhi = lvitemlo;
				lvitemhi.iItem = nHi;
				lvitemhi.iSubItem = nCol; // 10/29/97

                
                // get the current lo and hi items
				GetItem( &lvitemlo );
				GetItem( &lvitemhi );
                
                // set item text of lo to item text of hi
				for( i=0; i< nColCount; i++)
				    SetItemText(nLo, i, GetItemText(nHi, i) );
                
                // save hi item
				lvitemhi.iItem = nLo;
				bRet = SetItem( &lvitemhi );
                _ASSERTE(bRet);
                
                // set item text of hi to item text of lo
				for( i=0; i< nColCount; i++)
				    SetItemText(nHi, i, arrsRowText[i]);
                
                // save lo item
				lvitemlo.iItem = nHi;
                lvitemhi.iSubItem = nCol; // 10/29/97
                bRet = SetItem( &lvitemlo );
                _ASSERTE(bRet);
			}
			
			++nLo;
			--nHi;
		}
	}
	
	// If the right index has not reached the left side of array
	// must now sort the left partition.
	if( nLow < nHi )
		SortInImageOrder( nCol, bAscending , nLow, nHi);
	
	// If the left index has not reached the right side of array
	// must now sort the right partition.
	if( nLo < nHigh )
		SortInImageOrder( nCol, bAscending , nLo, nHigh );
	
	return TRUE;
}



Comments

  • bug

    Posted by lincolnfz on 01/13/2006 03:17am

    I have use this code in my program. I found some bugs in this code. If I only have one image type in listctrl it cant sort.

    Reply
  • Bug Report

    Posted by Legacy on 02/07/2002 12:00am

    Originally posted by: eric_chenwei

    I have use this code in my program. I found some bugs in this code. If I only have one image type in listctrl it cant sort.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • Businesses are moving more and more of their customer transactions to the web. Security is understandably a top concern as online transactions increase, so it is important to make sure your electronic signature provider meets the highest security standards. That means more than simply passing a security audit or obtaining a certification. This white paper provides recommendations for taking a broader view of e-signature security, and answers key questions that help identify the security requirements against …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds