Click here to Skip to main content
15,886,258 members
Articles / Desktop Programming / MFC
Article

CListCtrl - one of the Blonde classes in MFC

Rate me:
Please Sign up or sign in to vote.
3.50/5 (45 votes)
8 Dec 20021 min read 220.6K   33   36
Some dialogbox code to give the Blonde a clue

Introduction

I hate the CListCtrl class. Along with the CTreeCtrl, it's one of the most insanely unfinished classes in the entire MFC library. Don't bother arguing this point, my mind is made up, so you'll just end up being wrong anyway.

The problem

When I use a list control, I use it in report mode. Many of you probably also only use the CListCtrl in report mode. Lately, I've had cause to actually do something about some of the CListCtrl's shortcomings. I haven't had a reason yet to actually derive a new class, but I really should. This article discusses ways to take care of these things in your dialog box class itself. Deriving a new class and adding this behavior is left as an exercise for the reader.

What!? No function similar to GetCurSel()?

The CListBox control and the CComboBox control both have a function for retrieving the index number of the currently selected item. CListCtrl does NOT, so here's what I use.

int CMyDialog::GetSelectedItem()
{
    int nItem = -1;
    POSITION nPos = m_ctrlMyList.GetFirstSelectedItemPosition();
    if (nPos)
    {
        nItem = m_ctrlMyList.GetNextSelectedItem(nPos);
    }
    return nItem;
}

Item highlight quirks

Okay, so you have your list control, and you click an item and as expected, a highlight bar appears. Cool. Now, if you click the a blank area under the last item in the list control, what happens? I'll tell you what happens - the highlight bar goes away. That's all well and good, but if you call the function I gave you above, guess what index number it returns. Wrong, it's NOT -1 (as you might expect), it's the index of the last item that was highlighted (or selected). How do you fix it? Handle the OnClick... and OnRclick... functions

void CMyDlg::OnClickList(NMHDR* pNMHDR, LRESULT* pResult) 
{
    NM_LISTVIEW* pNM = (NM_LISTVIEW*)pNMHDR;
    int nCount = m_ctrlList.GetItemCount();
    LVHITTESTINFO ht;
    ht.pt = pNM->ptAction;
    m_ctrlList.SubItemHitTest(&ht);
    if (ht.iItem < 0 || ht.iItem > nCount)
    {
        int nItem = GetSelectedItem();
        // re-establish the highlight bar on the last selected item 
        // (taking advantage of the control's bug)
        m_ctrlList.SetItemState(nItem, 
            LVIS_SELECTED, LVIS_SELECTED | LVIS_FOCUSED);
    }
    else
    {
        // highlight the item selected
        m_ctrlHostList.SetItemState(ht.iItem, 
            LVIS_SELECTED, LVIS_SELECTED | LVIS_FOCUSED);
    }
    *pResult = 0;
}

void CMyDlg::OnRclickList(NMHDR* pNMHDR, LRESULT* pResult) 
{
    NM_LISTVIEW* pNM = (NM_LISTVIEW*)pNMHDR;
    int nCount = m_ctrlList.GetItemCount();
    if (nCount > 0)
    {
        LVHITTESTINFO ht;
        ht.pt = pNM->ptAction;
        m_ctrlList.SubItemHitTest(&ht);
        if (ht.iItem < 0 || ht.iItem > nCount)
        {
            int nItem = GetSelectedItem();
            m_ctrlList.SetItemState(nItem, 
                LVIS_SELECTED, LVIS_SELECTED | LVIS_FOCUSED);
        }
        else
        {
            m_ctrlList.SetItemState(ht.iItem, 
                LVIS_SELECTED, LVIS_SELECTED | LVIS_FOCUSED);
        }
    }
    *pResult = 0;
}

Have a ball, and remember, I've only used this in report mode.

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


Written By
Software Developer (Senior) Paddedwall Software
United States United States
I've been paid as a programmer since 1982 with experience in Pascal, and C++ (both self-taught), and began writing Windows programs in 1991 using Visual C++ and MFC. In the 2nd half of 2007, I started writing C# Windows Forms and ASP.Net applications, and have since done WPF, Silverlight, WCF, web services, and Windows services.

My weakest point is that my moments of clarity are too brief to hold a meaningful conversation that requires more than 30 seconds to complete. Thankfully, grunts of agreement are all that is required to conduct most discussions without committing to any particular belief system.

Comments and Discussions

 
Generala shorter way Pin
dis141113-Mar-06 17:31
dis141113-Mar-06 17:31 

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

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