区分 CListCtrl 中的用户单击和 SetChecked()
Posted
技术标签:
【中文标题】区分 CListCtrl 中的用户单击和 SetChecked()【英文标题】:Differentiate between user click and SetChecked() in CListCtrl 【发布时间】:2015-02-18 11:37:33 【问题描述】:我有一个带有复选框的 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
的检查能让我区分点击和功能,但事实并非如此。
除了在函数调用之前/之后设置一些全局标志并在回调中使用之外,还有其他方式来判断是使用点击还是函数调用?
【问题讨论】:
如果您需要根据某些条件启用/禁用,为什么禁用滚动条(和整个控件)很重要?听起来您正在实现非标准 UI 行为。 为什么这是非标准的?我想查看列表中的所有复选框条目,但我不想切换这些条目。类似于显示编辑框但禁用编辑功能。 为什么使用INDEXTOSTATEIMAGEMASK
?你应该使用LVIS_STATEIMAGEMASK
相关(问题 2):***.com/questions/41176599/…
【参考方案1】:
我在我的程序中使用相同的,我使用了一个标志。
但我使用的是 LVN_ITEMCHANGING。有了这条消息,我可以阻止任何更改。
我在更改列表框项的状态之前覆盖了 SetCheck(即使它不是虚拟的)并设置了一个标志。内部 OnItemChanging 例程看到标志集并允许更改。返回后直接清除flag。
因此,如果使用鼠标执行相同的操作,则未设置标志,您需要以不同的方式进行检查。
装箱时也是这样。我设置了flag,让所有的变化都能通过……
【讨论】:
我选择了一个类似的解决方案,其标志在SetCheck()
之前/之后切换,这可行,但感觉有点笨拙。
是的。但即使寻找最后收到的 Window 消息也无济于事。您需要“动作”的上下文。一种上下文是“程序动作”,一种上下文是“用户动作”。以上是关于区分 CListCtrl 中的用户单击和 SetChecked()的主要内容,如果未能解决你的问题,请参考以下文章