Click here to Skip to main content
11,577,710 members (42,126 online)
Click here to Skip to main content

Sort List Control

, 17 Nov 2003 74.1K 2.6K 23
Rate this:
Please Sign up or sign in to vote.
A list control with sorting indicator.

Sample Image - sortlistviewctrl.jpg

Introduction

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.

Background

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?

Loading Bitmaps

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 LoadLibrary instead.

After loading the bitmaps, we can draw them on the header control just as we draw other bitmaps.

Sorting

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>
{
public:
    enum Field
    {
        Filename = 0,
        Size,
        Time
    };

    CFileStruct(LPCTSTR szFilename,ULONGLONG nSize,FILETIME ftTime);
    int Compare(CFileStruct* pItem,int nField);
    CString Format(int nField);

protected:
    CString m_szFilename;
    ULONGLONG m_nSize;
    FILETIME m_ftTime;
};

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.

CSortListViewCtrl<CFileStruct> m_List;

To subclass the control, we can call SubclassWindow or simply use the operator = which wraps the subclassing method.

m_List=GetDlgItem(IDC_LIST1);

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 LVN_DELETEITEM command.

The control should handle all sorting by itself. If you want to sort it by yourself, you can call the Sort function.

To implement the control, you must follow these steps:

  • Derive your own class from CSortListViewCtrlItem and implement the Compare function.
  • 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 REFLECT_NOTIFICATIONS macro.

Sample application

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.

Final notes

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 Smile | :) ).

History

November 18, 2003 - First public release.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Gilad Novik
Web Developer
Israel Israel
Gilad was born accidently to a pair of old lesbians. His childhood was full of vibrators and drugs. Married without kids. Has 14 grandsons around the world, 4 crocodiles, 2 mushrooms and a green alien living behind the refrigerator.

Hobbies: Watching hardcore porn, sculpturing with snot, skydiving from stairs.

Check my Homepage for additional resources.

Quote: "There's always one more bug"

You may also be interested in...

Comments and Discussions

 
QuestionIn what situation we can not locate Shell32.dll in memory? Pin
Hunt Chang1-May-08 6:46
memberHunt Chang1-May-08 6:46 
Generalerror C3203, VC8(/msvs2005 pro,sp1) Pin
Harly8-Jun-07 4:07
memberHarly8-Jun-07 4:07 
GeneralRe: error C3203, VC8(/msvs2005 pro,sp1) Pin
Harly8-Jun-07 4:27
memberHarly8-Jun-07 4:27 
GeneralRe: error C3203, VC8(/msvs2005 pro,sp1) Pin
hpking22-Aug-10 18:02
memberhpking22-Aug-10 18:02 
QuestionCListViewCtrl Pin
Carlos_Lopez24726-Jan-06 3:40
memberCarlos_Lopez24726-Jan-06 3:40 
GeneralSubclassWindow =(HWND hwnd) Pin
Skandal31-Jul-04 8:14
memberSkandal31-Jul-04 8:14 
Hi Gilad!

First, I'd like to thank you for a great wtl sample=)

I'm having some trouble using the control in a dialog with SubClassWindow.

HWND t_hWnd=m_Dialog.GetDlgItem(IDC_LIST);
     CSortListViewCtrl<MyItem> list;
     //CListViewCtrl list;

     list=t_hWnd; //subclassing operator
     list.InsertColumn(0, _T("ID"),LVCFMT_LEFT,40,0);

When I use the regular listview ctrl, this sample works great. But when I use the CSortListViewCtrl the objects destructor is called and the program
asserts false in ~CWindowImplRoot and I get the nasty ATLTRACE "ERROR - Object deleted before window was destroyed". I have no clue why this happens at all. Am I missing something which is required for using the control in a dialog?

Best Regards,

Fredrik


GeneralProblem Solved Pin
Skandal31-Jul-04 11:14
memberSkandal31-Jul-04 11:14 
GeneralBetter look with Windows XP Pin
Michal Mecinski19-Nov-03 1:51
memberMichal Mecinski19-Nov-03 1:51 
GeneralHandy Pin
WREY18-Nov-03 20:09
memberWREY18-Nov-03 20:09 
GeneralDemo Doesn't Work Pin
Mike O'Neill18-Nov-03 10:15
memberMike O'Neill18-Nov-03 10:15 
GeneralRe: Demo Doesn't Work Pin
Gilad Novik18-Nov-03 21:21
memberGilad Novik18-Nov-03 21:21 
GeneralRe: Demo Doesn't Work Pin
Gilad Novik18-Nov-03 21:33
memberGilad Novik18-Nov-03 21:33 
GeneralRe: Demo Doesn't Work Pin
Greh2-Feb-05 20:48
memberGreh2-Feb-05 20:48 
GeneralNice Bio! Pin
Jim Crafton18-Nov-03 8:08
memberJim Crafton18-Nov-03 8:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150603.1 | Last Updated 18 Nov 2003
Article Copyright 2003 by Gilad Novik
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid