Click here to Skip to main content
11,495,534 members (63,092 online)
Click here to Skip to main content

An Extended MFC CListCtrl to edit individual cells, sort headers, and more

, 23 Jul 2008 CPOL 107.5K 9.9K 59
Rate this:
Please Sign up or sign in to vote.
The MFC CListCtrl does not allow editing labels for all columns. This extended class implements ways to specify column editors, row, cell, and column colors etc.

Introduction

This article explains a very flexible way to specify a row, column, or cell editor, color or sorting features.

untitled1.JPG

Background

I was looking for a list control that allows me to edit each column label separately and specify the editor of my choice like a DateTimePicker, or ComboBox, or TextBox, or even a dialog box. So, I extended and created this list control.

Using the code

Using CListCtrlEx is very similar to using CListCtrl. A few extra methods have been added to ease label editing and sorting. Following are the additional functions added to the list control:

void SetColumnEditor(int nColumn, PFNEDITORCALLBACK pfnInitEditor, 
     PFNEDITORCALLBACK m_pfnEndEditor = NULL,  CWnd* pWnd = NULL);
void SetColumnEditor(int nColumn, CWnd* pWnd);
void SetCellEditor(int nRow, int nColumn, PFNEDITORCALLBACK pfnInitEditor, 
     PFNEDITORCALLBACK m_pfnEndEditor = NULL,  CWnd* pWnd = NULL);
void SetCellEditor(int nRow, int nColumn, CWnd* pWnd);
void SetRowEditor(int nRow, PFNEDITORCALLBACK pfnInitEditor, 
     PFNEDITORCALLBACK m_pfnEndEditor = NULL,  CWnd* pWnd = NULL);
void SetRowEditor(int nRow, CWnd* pWnd);
void SetDefaultEditor(PFNEDITORCALLBACK pfnInitEditor, 
     PFNEDITORCALLBACK m_pfnEndEditor = NULL,  CWnd* pWnd = NULL);
void SetDefaultEditor(CWnd* pWnd); 
         
void SetColumnReadOnly(int nColumn, bool bReadOnly = true);
void SetCellReadOnly(int nRow, int nColumn, bool bReadOnly = true);
void SetRowReadOnly(int nRow, bool bReadOnly = true);

void SetRowColors(int nItem, COLORREF clrBk, COLORREF clrText);
void SetColumnColors(int nColumn, COLORREF clrBack, COLORREF clrText);
void SetCellColors(int nRow, int nColumn, COLORREF clrBack, COLORREF clrText);
 
BOOL DisplayEditor(int nItem, int nSubItem);
void HideEditor(BOOL bUpdate = TRUE);

void DeleteSelectedItems(void);
//Delete selected items when delete key is pressed
void HandleDeleteKey(BOOL bHandle = TRUE);
void SelectItem(int nItem, BOOL bSelect);
BOOL DeleteAllColumns(void);
BOOL Reset(void);

void SetColumnSorting(int nColumn, Sort eSort, Comparer eSortType = String);
void SetColumnSorting(int nColumn, Sort eSort, PFNLVCOMPARE fnCallBack);
BOOL SortOnColumn(int nColumn, BOOL bChangeOrder = FALSE);
 
BOOL IsColumnReadOnly(int nColumn);
BOOL IsRowReadOnly(int nRow);
BOOL IsCellReadOnly(int nRow, int nColumn);

The following code explains how to use the extended list control in your dialog:

BOOL CDemoDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    ...
    //Set image list to increase row height
    m_imgList.Create(1, 20, ILC_COLOR, 0, 1);
    m_lstDemo.SetImageList(&m_imgList, LVSIL_SMALL);
    FillListBox();
    m_lstDemo.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
    //set full row select and grid lines

    return TRUE;
    // return TRUE  unless you set the focus to a control
}

void CDemoDlg::AddColumns(void)
{
    m_lstDemo.InsertColumn(0, "Default Editor", LVCFMT_LEFT, 100);
    m_lstDemo.InsertColumn(1, "Date Time Editor", LVCFMT_LEFT, 100);
    m_lstDemo.InsertColumn(2, "Combobox Editor", LVCFMT_LEFT, 100);
    m_lstDemo.InsertColumn(3, "Color Select", LVCFMT_LEFT, 150);
    m_lstDemo.InsertColumn(4, "Read Only Column", LVCFMT_LEFT, 100);
    m_lstDemo.InsertColumn(5, "Just a Column", LVCFMT_LEFT, 100);

    m_lstDemo.SetColumnEditor(1, &CDemoDlg::InitEditor, 
                                 &CDemoDlg::EndEditor, &m_wndDT);
    m_lstDemo.SetColumnEditor(2, &CDemoDlg::InitEditor, 
                                 &CDemoDlg::EndEditor, &m_wndCB);
    m_lstDemo.SetColumnEditor(3, &CDemoDlg::InitEditor, 
                                 &CDemoDlg::EndEditor, &m_dlgColor);
    m_lstDemo.SetColumnReadOnly(4);
    m_lstDemo.SetDefaultEditor(NULL, NULL, &m_wndEdit);
    m_lstDemo.SetColumnColors(4, RGB(200, 200, 200), RGB(128, 128, 128));
    m_lstDemo.SetColumnSorting(0, CListCtrlEx::Auto, CListCtrlEx::StringNoCase);
    m_lstDemo.SetColumnSorting(1, CListCtrlEx::Auto, CListCtrlEx::Date);
    m_lstDemo.SetColumnSorting(2, CListCtrlEx::Auto, CListCtrlEx::String);
    m_lstDemo.SetColumnSorting(3, CListCtrlEx::Auto, CListCtrlEx::StringNoCase);
    m_lstDemo.SetColumnSorting(4, CListCtrlEx::Auto, CListCtrlEx::StringNoCase);
}

void CDemoDlg::FillListBox(void)
{
    m_lstDemo.Reset();
    AddColumns();
    CString strDate = COleDateTime(CTime::GetCurrentTime().GetTime()).Format();
    for(int i = 0; i < 20; i++)
    {
        CString str;
        str.Format("Some %d Text %d", rand(), rand());
        m_lstDemo.InsertItem(i, str);
        m_lstDemo.SetItemText(i, 1, strDate);
        m_lstDemo.SetItemText(i, 2, "text1");
        m_lstDemo.SetItemText(i, 3, "Some Text");
        m_lstDemo.SetItemText(i, 4, "Read Only");
        m_lstDemo.SetItemText(i, 5, "Some Text");
        if(i%9 == 3)
        {
            m_lstDemo.SetRowColors(i, -1, RGB(255, 0, 0));
            m_lstDemo.SetRowEditor(i, NULL, NULL, &m_wndEdit);
        }
        if(i % 7 == 0)
        {
            m_lstDemo.SetCellColors(i, 5, RGB(0, 255, 0), RGB(255, 255, 255));
            m_lstDemo.SetCellEditor(i, 5, &CDemoDlg::InitEditor, 
                                    &CDemoDlg::EndEditor, &m_wndDT);
        }
        if(i % 8 == 0) m_lstDemo.SetCellColors(i, 5, RGB(0, 255, 0), -1);
    }
    
}
//Call back function to initialize the cell editor.
BOOL
CDemoDlg::InitEditor(CWnd** pWnd, int nRow, int nColumn, CString&
strSubItemText, DWORD_PTR dwItemData, void* pThis, BOOL bUpdate)
{
    ASSERT(*pWnd);
    switch(nColumn)
    {
    case 1:
    case 5:
        {
            CDateTimeCtrl *pDTC = dynamic_cast<CDateTimeCtrl *>(*pWnd);
            COleDateTime dt;
            if(dt.ParseDateTime(strSubItemText)) pDTC->SetTime(dt);
        }
        break;
    case 2:
        {
            CComboBox *pCmb = dynamic_cast<CComboBox *>(*pWnd);
            pCmb->SelectString(0, strSubItemText);
        }
        break;
    case 3:
        {
            CDlgColor *pDlg = dynamic_cast<CDlgColor *>(*pWnd);        
            pDlg->m_nColor = strSubItemText.CompareNoCase("green")? 
               (strSubItemText.CompareNoCase("blue")?0:2):1;
            pDlg->Create(CDlgColor::IDD, (CWnd*)pThis);            
            pDlg->UpdateData(FALSE);
        }
        break;
    }
    return TRUE;
}
 
//Call back function to end and destroy the cell editor.
//Spacial feature return -1 to sort list control items 
//based on the current editing item.
BOOL CDemoDlg::EndEditor(CWnd** pWnd, int nRow, int nColumn, 
                         CString& strSubItemText, 
                         DWORD_PTR dwItemData, 
                         void* pThis, BOOL bUpdate)
{
    ASSERT(pWnd);
    switch(nColumn)
    {
    case 1:
    case 5:
        {
            CDateTimeCtrl *pDTC = dynamic_cast<CDateTimeCtrl *>(*pWnd);
            COleDateTime dt;
            pDTC->GetTime(dt);
            strSubItemText = dt.Format();
        }
        break;
    case 2:
        {
            CComboBox *pCmb = dynamic_cast<CComboBox *>(*pWnd);
            int index = pCmb->GetCurSel();
            if(index >= 0) pCmb->GetLBText(index, strSubItemText);
        }
        break;
    case 3:
        {
            CDlgColor *pDlg = dynamic_cast<CDlgColor *>(*pWnd);
            CListCtrlEx *pList = reinterpret_cast<CListCtrlEx *>(pThis);
            pDlg->UpdateData(TRUE);
            switch(pDlg->m_nColor)
            {
            case 1:
                strSubItemText = "Green";
                pList->SetCellColors(nRow, nColumn, RGB(0, 255, 0), -1);
                break;
            case 2:
                strSubItemText = "Blue";
                pList->SetCellColors(nRow, nColumn, RGB(0, 0,255 ), -1);
                break;
            default:
                strSubItemText = "Red";
                pList->SetCellColors(nRow, nColumn, RGB(255, 0, 0), -1);
                break;
            }                
            pDlg->DestroyWindow();
        }
        break;
    }
    return TRUE;
}

I hope the code is self explanatory; if not, just post a question. Also have a look at the demo project.

License

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

Share

About the Author

Sanjay1982
Software Developer
India India
I have been involved in C, C++ development for over a six year now. I have worked on projects involving games, insurance application, stats and reporting applications. Being busy with work I hardly got time to post my own articles but now I am getting more involved. I don't promise much but hopefully you'll see some more interesting articles from me in near future.

Comments and Discussions

 
QuestionMessage Removed Pin
Flaviu212-Apr-15 5:44
memberFlaviu212-Apr-15 5:44 
QuestionMemory leak when use SetItemData Pin
Annie_Wu10-Nov-13 17:36
memberAnnie_Wu10-Nov-13 17:36 
AnswerRe: Memory leak when use SetItemData Pin
Sanjay198211-Nov-13 5:30
memberSanjay198211-Nov-13 5:30 
GeneralRe: Memory leak when use SetItemData Pin
Annie_Wu26-Dec-13 15:45
memberAnnie_Wu26-Dec-13 15:45 
NewsGet Highlight Selected Items on CListCtrl when there is no Focus Pin
MaxMax1418-Oct-13 8:57
memberMaxMax1418-Oct-13 8:57 
QuestionCombobox drop list not visible Pin
nitin vasishtha10-Jul-13 23:32
membernitin vasishtha10-Jul-13 23:32 
QuestionYou will find bug after input value Pin
Jacky Zhou9-Jul-13 23:23
memberJacky Zhou9-Jul-13 23:23 
GeneralMy vote of 5 Pin
Vinicius Pontes16-May-13 4:25
memberVinicius Pontes16-May-13 4:25 
Questionload image from file using mfc Pin
saharanvikas0130-Oct-12 7:53
membersaharanvikas0130-Oct-12 7:53 
AnswerRe: load image from file using mfc Pin
Sanjay198230-Oct-12 16:08
memberSanjay198230-Oct-12 16:08 
QuestionBlack lines after dynamic Create Pin
NewBe8110-Oct-12 5:09
memberNewBe8110-Oct-12 5:09 
Questionborder in editBox Pin
Auriga_dorado21-Sep-12 5:57
memberAuriga_dorado21-Sep-12 5:57 
AnswerRe: border in editBox Pin
Sanjay198225-Sep-12 21:38
memberSanjay198225-Sep-12 21:38 
GeneralRe: border in editBox Pin
Auriga_dorado25-Sep-12 22:33
memberAuriga_dorado25-Sep-12 22:33 
SuggestionAdd support for Enter key Pin
Member 856192622-Feb-12 1:33
memberMember 856192622-Feb-12 1:33 
GeneralRe: Add support for Enter key Pin
Sanjay198223-Feb-12 16:27
memberSanjay198223-Feb-12 16:27 
Questiontoo few comments, not easy to understand. But thanks anyway. Pin
goudan09081520-Dec-11 22:22
membergoudan09081520-Dec-11 22:22 
QuestionHow can you do the same in an SDI or MDI application? Pin
Member 813405016-Sep-11 11:50
memberMember 813405016-Sep-11 11:50 
QuestionI don't understand your code. Can U show me some document about it? Pin
vanhung221022-Mar-11 7:28
membervanhung221022-Mar-11 7:28 
GeneralPLEASE HELP ME. Error when i try compiling (F7) in vs2008 Pin
vanhung221015-Mar-11 0:01
membervanhung221015-Mar-11 0:01 
GeneralRe: PLEASE HELP ME. Error when i try compiling (F7) in vs2008 Pin
Sanjay198215-Mar-11 0:52
memberSanjay198215-Mar-11 0:52 
GeneralRe: PLEASE HELP ME. Error when i try compiling (F7) in vs2008 Pin
vanhung221015-Mar-11 4:28
membervanhung221015-Mar-11 4:28 
GeneralRe: PLEASE HELP ME. Error when i try compiling (F7) in vs2008 Pin
jo le serb20-Mar-12 4:19
memberjo le serb20-Mar-12 4:19 
GeneralI cannot find where you initialize the combobox choices to text1, text2, text3. Pin
mjcrawford29-Dec-10 11:44
membermjcrawford29-Dec-10 11:44 
GeneralRe: I cannot find where you initialize the combobox choices to text1, text2, text3. Pin
Sanjay19829-Dec-10 22:31
memberSanjay19829-Dec-10 22:31 
GeneralRe: I cannot find where you initialize the combobox choices to text1, text2, text3. Pin
Member 813405016-Sep-11 11:58
memberMember 813405016-Sep-11 11:58 
GeneralVC6 project with few pluses [modified] Pin
mesajflaviu1-Dec-10 7:46
membermesajflaviu1-Dec-10 7:46 
GeneralHaving a real hard time using InitEditor() and EndEditor() Pin
IceTeaPeche23-Aug-10 6:50
memberIceTeaPeche23-Aug-10 6:50 
GeneralRe: Having a real hard time using InitEditor() and EndEditor() Pin
Sanjay198223-Aug-10 20:02
memberSanjay198223-Aug-10 20:02 
GeneralRe: Having a real hard time using InitEditor() and EndEditor() Pin
IceTeaPeche24-Aug-10 7:10
memberIceTeaPeche24-Aug-10 7:10 
GeneralPressing ENTER while editing closes the dialog instead of just finishing editing Pin
MindJuice18-Aug-10 16:12
memberMindJuice18-Aug-10 16:12 
GeneralRe: Pressing ENTER while editing closes the dialog instead of just finishing editing Pin
Sanjay198223-Aug-10 20:25
memberSanjay198223-Aug-10 20:25 
GeneralMy vote of 5 Pin
zeroliql30-Jul-10 9:02
memberzeroliql30-Jul-10 9:02 
QuestionDoes anybody know how to catch edit values ? Pin
mesajflaviu4-May-10 1:14
membermesajflaviu4-May-10 1:14 
AnswerRe: Does anybody know how to catch edit values ? Pin
Sanjay19825-May-10 7:33
memberSanjay19825-May-10 7:33 
GeneralRe: Does anybody know how to catch edit values ? Pin
mesajflaviu7-May-10 6:38
membermesajflaviu7-May-10 6:38 
GeneralBlack blackground when I spread on CView ! [modified] Pin
mesajflaviu18-Mar-10 1:53
membermesajflaviu18-Mar-10 1:53 
GeneralRe: Black blackground when I spread on CView ! Pin
mesajflaviu18-Mar-10 21:05
membermesajflaviu18-Mar-10 21:05 
GeneralRe: Black blackground when I spread on CView ! Pin
jtbmadrid23-Sep-10 21:41
memberjtbmadrid23-Sep-10 21:41 
GeneralColumn Sorting Pin
mattfaramir3314-Mar-10 9:40
membermattfaramir3314-Mar-10 9:40 
GeneralRe: Column Sorting Pin
Member 92643715-Dec-10 22:33
memberMember 92643715-Dec-10 22:33 
GeneralScreen Flicker Pin
mattfaramir3314-Mar-10 9:37
membermattfaramir3314-Mar-10 9:37 
QuestionDraw symbol in sub item after combobox hidden? Pin
JezzerP8-Dec-09 0:28
memberJezzerP8-Dec-09 0:28 
GeneralUser Data Pin
mhalaj29-Oct-09 1:36
membermhalaj29-Oct-09 1:36 
GeneralRe: User Data Pin
Sanjay198229-Oct-09 5:51
memberSanjay198229-Oct-09 5:51 
QuestionControls visible all the time Pin
JezzerP27-Oct-09 1:52
memberJezzerP27-Oct-09 1:52 
Question[Message Deleted] Pin
JezzerP28-Oct-09 1:25
memberJezzerP28-Oct-09 1:25 
AnswerRe: Controls visible all the time Pin
Sanjay198228-Oct-09 5:24
memberSanjay198228-Oct-09 5:24 
GeneralRe: Controls visible all the time Pin
JezzerP28-Oct-09 6:51
memberJezzerP28-Oct-09 6:51 
GeneralRe: Controls visible all the time Pin
Sanjay198228-Oct-09 8:21
memberSanjay198228-Oct-09 8:21 

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
Web03 | 2.8.150520.1 | Last Updated 23 Jul 2008
Article Copyright 2008 by Sanjay1982
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid