First thing, I would like to apologize for any grammar/spelling mistakes in the article. Since English isn't my native language, I tend to do a lot of mistakes while typing.
CListViewCtrl is a nice control, used mainly in report mode. You can see it filled with files when using Windows Explorer. The control also supports sorting mechanism using the
SortItems function. The main problem is that there is no sorting indicator.
When looking at some articles at Code Project, you can find two solutions. The first solution is to provide two additional resources of bitmaps - indicating the arrows for the header control. The second solution is an owner drawn header control which is capable of drawing the appropriate arrow.
Why bother? How does Microsoft draw its arrows? How does Window Explorer draw itself?
After looking at some files, I found out the solution. There are two bitmaps, located in shell32.dll. The up arrow is 133, while the down arrow is 134.
To load the appropriate bitmap, we use the
LoadImage function. Since most of the applications link themselves to shell32.dll, we can use the
GetModuleHandle function to retrieve the module handle. If our application doesn't link itself to shell32.dll, we can use
After loading the bitmaps, we can draw them on the header control just as we draw other bitmaps.
To sort using the list control, we need to define a callback function. To avoid doing it manually, I've created a wrapper for a structure, which my list control can use.
Using the code
Since the report mode is some kind of a structure, we need to create our class to hold the relevant information. The class must inherit from
CSortListViewCtrlItem, and specify its class name as the template parameter. We will use a file structure which represents a single file:
class CFileStruct : public CSortListViewCtrlItem<CFileStruct>
Filename = 0,
CFileStruct(LPCTSTR szFilename,ULONGLONG nSize,FILETIME ftTime);
int Compare(CFileStruct* pItem,int nField);
CString Format(int nField);
The constructor initializes the structure, while the
Format function simply formats a specific field into a string.
The important function is
Compare. It compares the current structure with another one, depending on the specified field (you can check the implementation in maindlg.cpp).
Second, we need to create the list control object. The
CSortListViewCtrl is a template class which accepts the structure type as its parameter.
To subclass the control, we can call
SubclassWindow or simply use the operator
= which wraps the subclassing method.
To make the control work, we need to create a new structure dynamically (using the
new operator), and attach the structure pointer to the list item using the
SetItemData function. We don't need to delete the structure, since the control will delete it automatically when handling the
The control should handle all sorting by itself. If you want to sort it by yourself, you can call the
To implement the control, you must follow these steps:
- Derive your own class from
CSortListViewCtrlItem and implement the
- Create the control object with your own structure as its template parameter, and subclass it to the original list window.
- Reflect notifications from the control's parent using the
The sample application creates a list control, and fills it with files from your Windows folder. You can sort the files by their name, size or time stamp. There is also a tooltip support which displays the entire information regarding a single file.
The source code is provided as-is. You can use it freely and modify it as you want. If you release any application which uses it, I will appreciate getting an email from you (just for my ego :) ).
November 18, 2003 - First public release.