CListCtrl with checkboxes questions

这一生的挚爱 提交于 2019-12-18 09:44:06

问题


The List Control is defined as Single Selection on the resources.

Question 1

I want to have a checkbox on the header of first column of my CListCtrl. On the OnInitDialog I have

    m_list.SetExtendedStyle(m_list.GetExtendedStyle() | LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT);

    CString s;
    s.LoadString(IDS_COLUMN1);

    #ifndef HDS_CHECKBOXES
    // Copied from Microsoft SDKs\Windows\v7.0A\Include\CommCtrl.h
    #define HDS_CHECKBOXES  0x0400
    #endif 

    CHeaderCtrl& header = *m_list.GetHeaderCtrl();
    header.ModifyStyle(0, HDS_CHECKBOXES);


    #ifndef HDF_CHECKBOX
    // Copied from Microsoft SDKs\Windows\v7.0A\Include\CommCtrl.h    
    #define HDF_CHECKBOX  0x0040
    #endif 

    LVCOLUMN lc = { 0 };
    lc.mask = LVCF_FMT |LVCF_WIDTH |LVCF_TEXT | LVCF_SUBITEM;
    lc.fmt |= HDF_CHECKBOX;
    lc.cx = 96;
    lc.pszText = (TCHAR*) (LPCTSTR)s;

    m_list.InsertColumn(0, &lc);

It only presents the header's checkbox if I add in the extended |LVS_EX_AUTOCHECKSELECT, which I definitely not want because I desire that checking action and selection action will be used for different purposes.

Question 2

I need to set a boolean and mark thing as modified when user checks or unchecks an item. But I don't want this action to occur when inserting items, for example when filling the list at form loading, but it is triggered without my intention, as InsertItem triggers "a uncheck action" on OnItemChanged.

It obliged me to condition every insert with a m_is_inserting member flag:

    m_is_inserting = true;
    m_list.InsertItem(i, m_array[i]->GetName());
    m_is_inserting = false;

and react accordingly on the LVN_ITEMCHANGED handler

void CMyDialog::OnItemChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
    NMLISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

    if (pNMListView->uChanged & LVIF_STATE)
    {
        if (pNMListView->uNewState & LVIS_SELECTED)
            OnSelect();
        else
        {
            if (pNMListView->iItem != -1)
            {
                if ((pNMListView->uNewState & LVIS_STATEIMAGEMASK) == 0x1000)
                {
                    if (!m_is_inserting)
                    {
                        m_array[pNMListView->iItem]->m_active = false;
                        SetModified();
                    }
                }
                else if ((pNMListView->uNewState & LVIS_STATEIMAGEMASK) == 0x2000)
                {
                    if (!m_is_inserting)
                    {
                        m_array[pNMListView->iItem]->m_active = true;
                        SetModified();
                    }
                }
            }
        }
    }

    *pResult = 0;
}

Is there a better way to distinguish a real user check/uncheck action from a InsertItem side effect?

Question 3

Is there a better symbolic convention for getting the check/uncheck state? Magic numbers 0x1000 and 0x2000 are pretty meaningless!

Thanks in advance.


回答1:


Insert the column headers first. Then change the HDF_CHECKBOX. For example:

m_list.SetExtendedStyle(LVS_EX_CHECKBOXES| LVS_EX_FULLROWSELECT);

CHeaderCtrl &header = *m_list.GetHeaderCtrl();
header.ModifyStyle(0, HDS_CHECKBOXES);

m_list.InsertColumn(0, L"Column0", 0, 120, 0);
m_list.InsertColumn(1, L"Column1", 0, 80, 1);
m_list.InsertColumn(2, L"Column2", 0, 80, 2);

HDITEM hdi = { 0 };
hdi.mask = HDI_FORMAT;
header.GetItem(0, &hdi);
hdi.fmt |= HDF_CHECKBOX;
header.SetItem(0, &hdi);

m_list.InsertItem(m_list.GetItemCount(), L"C0", 0);
m_list.InsertItem(m_list.GetItemCount(), L"C1", 0);

m_list.SetCheck(0, 1);
m_list.SetCheck(1, 1);

When handling the notification you can use the GetCheck method to see if item is checked or not. Example:

if(pNMListView->uChanged & LVIF_STATE)
{
    if(pNMListView->uNewState & LVIS_SELECTED)
    {
        ...
    }
    else if(pNMListView->uNewState & LVIS_STATEIMAGEMASK && pNMListView->iItem >= 0)
    {
        if(m_list.GetCheck(pNMListView->iItem))
            TRACE("%d checked\n", pNMListView->iItem);
    }
}


来源:https://stackoverflow.com/questions/41176599/clistctrl-with-checkboxes-questions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!