当用户在CListCtrl中选择行时,我想执行一些代码(报表视图,我不关心其他查看模式)。
如何捕获此事件?是否有一些消息可以映射或类似于“OnSelectionChanged”这样的方法?
当用户在CListCtrl中选择行时,我想执行一些代码(报表视图,我不关心其他查看模式)。
如何捕获此事件?是否有一些消息可以映射或类似于“OnSelectionChanged”这样的方法?
也可以尝试:
BEGIN_MESSAGE_MAP(cDlgRun, CDialog)
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST2, OnItemchangedList2)
END_MESSAGE_MAP()
/* ... */
void cDlgRun::OnItemchangedList2(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
if ((pNMListView->uChanged & LVIF_STATE)
&& (pNMListView->uNewState & LVIS_SELECTED))
{
// do stuff...
}
}
根据正在发生的操作,会有一些通知。
如果你正在选择一个项目并且还没有选中任何内容,你将会得到一个基于 LVIF_STATE 变化的通知:uNewState & LVIS_SELECTED。新选择的项目会在以下位置找到:
pNMListView->iItem
如果在你选择新对象之前已经选择了某个项目,你会得到三个状态变化:
首先,你会收到通知,表示以前焦点所在的项目正在失去焦点:
pNMListView->uOldState & LVIS_FOCUSED
然后您将收到通知,提示旧项目正在取消选择:
pNMListView->uOldState & LVIS_SELECTED
最终,您将获得新的项目选择状态:
pNMListView->uNewState & LVIS_SELECTED
(再次查看iItem以获取新选择的项目)
因为取消选择会导致两个通知,我们遇到的陷阱是我们进行了很多重复的、有时是有害的处理。我们最终做的是仅针对第二条消息(pNMListView->uOldState & LVIS_SELECTED)
执行此处理,并在失去焦点通知后跳过相同的处理。
LVN_ITEMCHANGED
函数会被多次调用是很重要的。有趣的是,前一个项目的状态LVIS_FOCUSED
和LVIS_SELECTED
是分别操作的。 - ripfreeworlddjeidot说得很对。
我想补充一下,ListView没有OnSelectionChanged()事件,因为它支持多选(虽然可以禁用)。因此,单选ListView会向您发送两个事件:旧项目取消选择和新项目选择。
afx_msg void OnLbnSelchangeListOnvif();
而在源文件中:
BEGIN_MESSAGE_MAP(CDialogOnvif, CDialog)
ON_LBN_SELCHANGE(IDC_LIST_ONVIF, &CDialogOnvif::OnLbnSelchangeListOnvif)
END_MESSAGE_MAP()
void CDialogOnvif::OnLbnSelchangeListOnvif()
{
// do stuff...
}
pNMListView->uChanged & LVIF_STATE
这个条件非常重要,因为如果你不检查它,在不期望的时刻会执行一些操作;在我的情况下,当我执行SetItemText
时就会触发这个条件。 - sergiol