Search code examples
visual-studiovisual-c++user-interfacemfclistctrl

CListCtrl with LVS_EX_CHECKBOXES style


I'm using CListCtrl with LVS_EX_CHECKBOXES style. And I need to have at least two of the checkboxes were set checked at any time.

How can I do this?


Solution

  • First you need to trap the LVN_ITEMCHANGING notification, which is most easily done by deriving your own class from CListCtrl (for example, called CMyListCtrl) and then adding a message map entry like the following:

    BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
        ON_NOTIFY_REFLECT(LVN_ITEMCHANGING, &CMyListCtrl::OnLvnItemchanging)
    END_MESSAGE_MAP()
    

    Then, you write the message handler like so:

    void CMyListCtrl::OnLvnItemchanging(NMHDR *pNMHDR, LRESULT *pResult)
    {
        // an item has changed
        LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    
        // by default, allow change
        *pResult = 0;
    
        // see if item was checked or unchecked
        if ((pNMLV->uNewState & 0x2000) == 0x2000)
        {
            // item was checked - do anything you like here
        }
        else if ((pNMLV->uNewState & 0x1000) == 0x1000)
        {
            // item was unchecked - see how many selections we have
            if (/* pseudocode */ number of selected items < 2)
            {
                // disallow change
                *pResult = 1;
            }
        }
    }
    

    The condition is pseudo-code so you can decide how to keep track of the number of selections - maybe keep a count by adding code to the above method, or put a loop in there to get the check state of each item and make a tally.

    I think this should give you enough to get moving, so please update your question if you get stuck further.