Click here to Skip to main content
Click here to Skip to main content

CListCtrl and Grouping Rows

, 27 Jul 2011
Rate this:
Please Sign up or sign in to vote.
Example of how to enable categories in the MFC list control

Introduction

Microsoft's CListCtrl has support for displaying data in a grid, but also supports grouping of data. This article will demonstrate how we can activate the grouping functionality of CListCtrl.

The demo application allows you to experience how grouping can be used. Just right-click a column header, to group the data according to that header.

screenshot.png

Background

Microsoft extended the CListCtrl with support for grouping, with the release of Windows XP. The new feature wasn't promoted that much, and was also limited in functionality (no collapsing of groups). The implementation was later extended with more functionality when Windows Vista was released (collapsing, footer, subtitle, and more).

There are already some .NET articles describing how to use grouping in Windows XP:

There is also MSDN - Windows Vista Control Enhancements, which describes some of the new stuff in Windows Vista.

The first time I actually saw a useful application make use of this grouping feature was with TortoiseSVN 1.5.

How To Activate Grouping in CListCtrl

Before grouping can be activated, some things have to be in order:

  • The Operating System must support Common Controls ver. 6 (Windows XP/Vista and newer)
  • The application must enable Common Controls ver. 6 through its manifest
  • The application must be compiled with _WIN32_WINNT set to at least 0x0501

When the above requirements are met, we can create a group like this:

LRESULT CListCtrl_Category_Groups::CreateSingleGroup(int nIndex, 
                  int nGroupId, const CString& strHeader)
{
    EnableGroupView( TRUE );
 
    LVGROUP lg = {0};
    lg.cbSize = sizeof(lg);
    lg.iGroupId = nGroupId;
    lg.state = LVGS_NORMAL;
    lg.mask = LVGF_GROUPID | LVGF_HEADER | LVGF_STATE | LVGF_ALIGN;
    lg.uAlign = LVGA_HEADER_LEFT;
 
    // Header-title must be unicode (Convert if necessary)
    lg.pszHeader = strHeader.GetBuffer();
    lg.cchHeader = strHeader.GetLength();
    nGroupId = InsertGroup(nIndex, &lg );
    if (nGroupId==-1)
        return nGroupId;
 
    // Insert all current items into this group
    for(int nRow = 0; nRow < GetItemCount(); ++nRow)
    {
        LVITEM lvItem = {0};
        lvItem.mask = LVIF_GROUPID;
        lvItem.iItem = nRow;
        lvItem.iSubItem = 0;
        lvItem.iGroupId = nGroupID;
        SetItem( &lvItem );
    }
}

The above example code creates a new group with the following properties:

  • The group will be inserted at nIndex in the CListCtrl internal list of groups.
  • The group will get the external identifier nGroupId.
  • The group headline will become the text-string strHeader.

Limitations in Windows XP

When working with groups on Windows XP, we will discover the following are missing:

  • It is not possible to ask how many groups there are in the CListCtrl internal list of groups. Instead, it is recommended to keep track of the created groups ourselves.
  • It is not possible to iterate over the groups in the CListCtrl internal list of groups. Instead, it is recommended to keep track of the created groups ourselves.
  • It is not possible to ask the CListCtrl if the mouse cursor is currently over a group. Instead, we have to do a lot of guessing.
  • It is not possible to change the group state, so it becomes collapsed.

These limitations have been solved with Windows Vista, and at the same time, the following features have been added:

  • Can attach a task-link to the group
  • Can provide a subtitle-text that is placed just below the header-text
  • Can provide a footer-text to the group

Using the Source Code

The source code provided demonstrates how to activate the different grouping features:

  • InsertGroupHeader() - Creates a new group. Wrapper around CListCtrl::InsertGroup().
  • SetRowGroupId() - Adds a row to an existing group. Wrapper around CListCtrl::SetItem() with LVIF_GROUPID.
  • GroupByColumn(int nCol) - Creates a new group for each unique cell text in the specified column.
  • SortColumn(int nCol) - Sorts the groups generated from the specified column. Wrapper around CListCtrl::SortGroups().
  • GroupHitTest(const CPoint& point) - Attempts to find the group below the given mouse point.
  • CheckEntireGroup() - When having the CListCtrl extended style LVS_EX_CHECKBOXES enabled, this method will change the check box state of an entire group.

It also demonstrates how to use some of the new Windows Vista features:

  • CollapseAllGroups() - Loops through all the groups and makes them collapse. Wrapper around CListCtrl::SetGroupInfo() with LVGS_STATE.
  • SetGroupTask() - Changes the task-link of a group. When the user clicks the task link, it will generate a LVN_LINKCLICK message.
  • SetGroupSubtitle() - Changes the subtitle of a group.
  • SetGroupFooter() - Changes the footer of a group.

History

  • 2008-09-16 - First release of the article
  • 2009-09-28 - Backport of bug-fixes from CGridListCtrlEx, and at startup it now groups the rows by the 3rd column
  • 2011-07-27 - Fixed bug in GroupHitTest() when used on Vista\Win7 and compiled with _WIN32_WINNT >= 0x0600

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Rolf Kristensen
Software Developer
Denmark Denmark
No Biography provided

Comments and Discussions

 
Questionhow can i group column Pinmemberyixuan17830-Jul-14 16:40 
AnswerRe: how can i group column PinpremiumRolf Kristensen30-Jul-14 20:20 
GeneralRe: how can i group column Pinmemberyixuan1781-Aug-14 4:43 
QuestionHow to change the style of Collapse Button? Pinmemberhandsome0317-Aug-13 21:32 
QuestionHow to change the header text color ? PinmemberMike Kuna21-Jun-13 2:58 
AnswerRe: How to change the header text color ? PinmemberRolf Kristensen22-Jun-13 0:04 
GeneralRe: How to change the header text color ? PinmemberMike Kuna25-Jun-13 3:18 
GeneralMy vote of 5 PinmemberMihai MOGA10-May-13 18:41 
GeneralMy vote of 5 PinmemberRiqiTang23-Feb-13 6:24 
GeneralMy vote of 5 PinmemberJJMatthews17-Jul-12 23:57 
QuestionSort by Numbers Pinmemberjens_weller31-May-12 23:32 
AnswerRe: Sort by Numbers PinmemberRolf Kristensen2-Jun-12 2:31 
QuestionGrouping and WM_SETFONT PinmemberDavide Zaccanti19-May-12 23:28 
QuestionIcon view problem PinmemberRohit Dubey from Hyderabad28-Feb-12 5:27 
GeneralGreat article. PinmemberRichard Hunn16-Nov-11 3:49 
GeneralMy vote of 5 PinmemberZhuJinYong21-Jul-11 23:09 
GeneralRe: My vote of 5 PinmemberRolf Kristensen26-Jul-11 10:10 
GeneralRe: My vote of 5 [modified] PinmemberZhuJinYong26-Jul-11 15:30 
GeneralRe: My vote of 5 PinmemberRolf Kristensen27-Jul-11 4:24 
GeneralRe: My vote of 5 [modified] PinmemberZhuJinYong27-Jul-11 4:39 
GeneralGreat! Pinmemberclxye14-Jul-11 15:03 
GeneralMy vote of 1 Pinmembertha_specializt8-Dec-10 4:01 
GeneralMy vote of 5 Pinmemberbondukanthikiran15-Jul-10 23:02 
GeneralDisable Header PinmemberPixbyte19-Jun-10 17:26 
GeneralRe: Disable Header PinmemberRolf Kristensen20-Jun-10 12:58 
QuestionHow could i use the control in VC++ 6.0 Pinmemberjelllove29-Dec-09 19:25 
AnswerRe: How could i use the control in VC++ 6.0 Pinmemberjelllove31-Dec-09 20:40 
GeneralRe: How could i use the control in VC++ 6.0 PinmemberSnakefoot3-Jan-10 5:31 
QuestionGrouping only apply for existing items? Pinmemberugly beast29-Oct-09 14:43 
AnswerRe: Grouping only apply for existing items? PinmemberSnakefoot29-Oct-09 21:17 
GeneralRe: Grouping only apply for existing items? Pinmembervngo30-Oct-09 19:39 
GeneralOwner Data ListCtrl Support PinmemberGerard Nicol30-Sep-09 11:23 
GeneralRe: Owner Data ListCtrl Support PinmemberSnakefoot30-Sep-09 12:03 
GeneralRe: Owner Data ListCtrl Support PinmemberGerard Nicol30-Sep-09 12:15 
GeneralRe: Owner Data ListCtrl Support [modified] PinmemberSnakefoot30-Sep-09 12:52 
GeneralI enjoy your CListCtrl articles. Pinmember Randor 29-Sep-09 16:45 
GeneralRe: I enjoy your CListCtrl articles. Pinmemberyarp29-Sep-09 20:18 
GeneralRe: I enjoy your CListCtrl articles. PinmemberSnakefoot29-Sep-09 21:46 
GeneralWorks fine... PinmemberJustADeveloper23-Sep-09 11:40 
GeneralMy vote of 1 PinmemberJohnSchu14-Sep-09 11:39 
GeneralRe: My vote of 1 PinmemberSnakefoot14-Sep-09 21:13 
GeneralRe: My vote of 1 PinmvpDavidCrow6-Oct-09 4:26 
GeneralMessage Automatically Removed Pinmembertha_specializt18-Aug-09 22:45 
GeneralRe: My vote of 1 PinmemberSnakefoot14-Sep-09 21:16 
GeneralRe: My vote of 1 PinmvpDavidCrow6-Oct-09 4:28 
GeneralRe: My vote of 1 Pinmembertha_specializt8-Dec-10 3:57 
Generalnot grouped under Windows XP PinmemberERLN24-Feb-09 6:47 
GeneralRe: not grouped under Windows XP PinmemberSnakefoot24-Feb-09 9:14 
GeneralRe: not grouped under Windows XP PinmemberERLN25-Feb-09 6:52 
GeneralRe: not grouped under Windows XP PinmemberSnakefoot26-Feb-09 4:27 

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 | Mobile
Web03 | 2.8.140814.1 | Last Updated 27 Jul 2011
Article Copyright 2008 by Rolf Kristensen
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid