Introduction
This article is based on Martin Ziacek's CQArray template class and Russell Robinson's COCArray template class. Please read their article before going on, I will mention the modifications only.
Motivation
I'm using a lot of lists (typically listviews) in my projects, with a lot of records. If you ever tried to place about 200.000 rows into a listview, you must know it's a nightmare! Moving in the list is very-very slow, memory allocation is very high, and if you want to retrieve any data (because the user has double clicked the row, for example), you have to convert your string to a "usable" data type. The owner data lists are much faster, but if you like to implement a sortable owner data list, you have to deal with the sorting. That's why I needed this CArrayEx
class.
Implementation
Using CArrayEx
is similar to using CArray
but you have to specify only 1 parameter in the declaration:
typedef struct
{
int index;
float fSomeFloat;
TCHAR SomeString[128];
} UserType;
CArrayEx<UserType> m_Data;
where UserType
is a user defined struct
.
For the sorting to be done, you have to declare a static member function in your class where you want the sorting to be done. For example, a CDocument
derived class (in the case of a Doc/View based application). If you have the procedure, then you have to tell the array to use that procedure for item compare, and then call QuickSort
by specifying the column number and sort direction.
The CDocument
derived part will look like this:
(in the .h file:)
static int CompareUserType(int iColumn, const UserType& udtLeft,
const UserType& udtRight);
(in the .cpp file:)
int CMyDocument::CompareUserType(int iColumn,
const UserType& udtLeft, const UserType& udtRight)
{
int iResult = 0;
switch(iColumn)
{
case 1:
if (udtLeft.index==udtRight.index)
iResult = 0;
else if (udtLeft.index&ludtRight.index)
iResult = -1;
else iResult = 1;
break;
case 2:
if (udtLeft.fSomeFloat==udtRight.fSomeFloat)
iResult = 0;
else if (udtLeft.fSomeFloat<udtRight.fSomeFloat)
iResult = -1;
else iResult = 1;
break;
case 3:
iResult = strcmp((char*)udtLeft.SomeString,
(char*)udtRight.SomeString);
break;
}
return iResult;
}
void CMyDocument::DoSort()
{
m_Data.SetCompareFunction(CompareUserType);
m_Data.QuickSort(1, TRUE);
}
It's easy, isn't it?
Final words
In the sample program (which was originally from Martin's article), you can specify an item count, and the type of sorting on an int
array and on a UserType
array.
I hope this class can save some time for a few people.
There is no copyright and the (un)usual stuff. :-)
Any improvements are welcome! Use this code free, but at your own risk.