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,让所有的变化都能通过...
我有一个带有复选框的 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,让所有的变化都能通过...