【问题标题】:How to detect a CListCtrl selection change?如何检测 CListCtrl 选择更改?
【发布时间】:2010-11-30 13:52:52
【问题描述】:

当用户在 CListCtrl 中选择一行时,我想执行一些代码(报表视图,我不关心其他查看模式)。

我如何捕捉这个事件?是否有一些我可以映射的消息或类似“OnSelectionChanged”之类的方法?

【问题讨论】:

    标签: visual-c++ mfc clistctrl


    【解决方案1】:

    也试试:

    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...
        }
    }
    

    【讨论】:

    • 当您使用 shift 选择三个元素但随后选择其中任何一个时,这不会捕捉到变化(这会取消选择另外两个,但保持选中此一个)。除了保留所选项目的列表之外,还有什么解决方法吗?
    • 我现在无法对其进行测试,但我认为您需要捕获取消选择以及选择:要捕获取消选择,只需使用 if ((pNMListView->uChanged & LVIF_STATE) && (pNMListView->uOldState & LVNI_SELECTED) && !(pNMListView->uNewState & LVNI_SELECTED))
    • @djeidot:非常感谢,它帮了大忙。当嵌入到自己的 Control 类中时,这也可以简化为 ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, &OnItemSelected)
    • @LS_dev 别担心,我确信它可以工作。 À confiança。
    • @djeidot 如果您还没有测试过,是什么让您如此确定?
    【解决方案2】:

    根据正在发生的事情有一些通知。

    如果您正在选择一个项目但尚未选择任何内容,您将收到一个 LVIF_STATE 更改通知:uNewState & LVIS_SELECTED。新选择的项目将在以下位置找到:

    pNMListView->iItem
    

    如果在您选择新对象之前选择了一个项目,您将获得三个状态更改:

    首先你会被告知上一个焦点正在失去焦点:

    pNMListView->uOldState & LVIS_FOCUSED
    

    然后会通知你旧项目正在被取消选中:

    pNMListView->uOldState & LVIS_SELECTED
    

    最后,你会得到新的项目选择状态:

    pNMListView->uNewState & LVIS_SELECTED
    

    (再次查看 iItem 以获取新选择的项目)

    所以我们遇到的陷阱是,因为取消选择项目会导致两个通知,我们做了很多重复的,有时是有害的处理。我们最终做的只是对第二条消息(pNMListView->uOldState & LVIS_SELECTED) 进行此处理,并在失去焦点通知后跳过相同的处理。

    【讨论】:

      【解决方案3】:

      djeidot 是正确的。

      我只想补充一点,没有 OnSelectionChanged() 因为 ListView 支持多选(尽管可以禁用)。因此,单选列表视图将向您发送两个事件:未选择旧项目和已选择新项目。

      【讨论】:

        【解决方案4】:

        在我的 Visual Studio 2010 上,可视化编辑器在对话框头文件中声明一个回调,如下所示:

        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...
        }
        

        【讨论】:

        • 这仅适用于列表框 (CListBox),不适用于 CListCtrl。
        猜你喜欢
        • 2012-05-10
        • 1970-01-01
        • 1970-01-01
        • 2013-05-10
        • 1970-01-01
        • 1970-01-01
        • 2022-01-18
        • 1970-01-01
        • 2013-10-31
        相关资源
        最近更新 更多