CListCtrl中用户点击和SetChecked()的区别

Differentiate between user click and SetChecked() in CListCtrl

我有一个带有复选框的 CListCtrl,我需要根据某些外部因素启用或禁用这些复选框。但是,当我在列表中有更多可以显示的项目时,我不能在控件上使用 EnableWindow(FALSE),因为它也会禁用滚动条。

所以,我在消息映射中搜索并得出以下代码:

ON_NOTIFY(LVN_ITEMCHANGED, IDC_CHECKBOX_LIST, OnCheckboxChanged)

回调函数实现为:

void CUserPropertiesDialog::OnCheckboxChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*) pNMHDR;
    LVHITTESTINFO hitInfo;

    hitInfo.pt = pNMListView->ptAction;
    int nItem = m_checkBoxList.HitTest(&hitInfo);
    if (hitInfo.flags != LVHT_ONITEMSTATEICON) return;

    std::string groupName = static_cast<LPCTSTR>(m_checkBoxList.GetItemText(nItem, 0));

    if (!CCharmUserAdminGUIApp::getTheCharmUserAdminGUIApp().isAdministrator())
    {
        if (pNMListView->uChanged & LVIF_STATE)
        {
            if (((pNMListView->uNewState & INDEXTOSTATEIMAGEMASK(2)) != 0) && ((pNMListView->uOldState & INDEXTOSTATEIMAGEMASK(1)) != 0))
            {
                CH_INFO1("CUserPropertiesDialog::OnCheckboxChanged - CheckBox Now Selected", groupName);
            }
            else if (((pNMListView->uNewState & INDEXTOSTATEIMAGEMASK(1)) != 0) && ((pNMListView->uOldState & INDEXTOSTATEIMAGEMASK(2)) != 0))
            {
                CH_INFO1("CUserPropertiesDialog::OnCheckboxChanged - CheckBox Now Unselected", groupName);
            }
        }
    }
}

问题在于,当用户单击复选框时会调用此函数(好!),而且当从代码调用 SetChecked() 函数时也会调用此函数。

我曾希望 hitInfo.flags 上的检查能让我区分点击和功能,但事实并非如此。

除了设置一些全局标志 before/after 函数调用并在回调中使用它之外,是否有任何其他方式来判断是否使用了点击或函数调用?

我在我的程序中使用了相同的,并且我使用了一个标志。

但是我用LVN_ITEMCHANGING。有了这条消息,我可以阻止任何更改。

我覆盖了 SetCheck(即使它不是虚拟的)并在我更改列表框项目的状态之前设置了一个标志。内部 OnItemChanging 例程看到标志集并允许更改。 return.

后直接清除flag

因此,如果使用鼠标完成相同的操作,则未设置标志,您需要以不同的方式进行检查。

装箱时也是如此。我设置了flag,让所有的变化都能通过...