65.9K
CodeProject 正在变化。 阅读更多。
Home

CListCtrl - MFC 中的一个“金发”

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.50/5 (45投票s)

2002年12月9日

1分钟阅读

viewsIcon

225262

一些对话框代码, 以便让“金发”明白

引言

我讨厌 CListCtrl 类。 连同 CTreeCtrl 一起,它是整个 MFC 库中最糟糕、最不完善的类之一。 别争论了,我的想法已经确定,你只会是错的。

问题所在

当我使用列表控件时,我总是使用报告模式。 你们中的许多人可能也只在报告模式下使用 CListCtrl。 最近,我需要解决 CListCtrl 的一些不足之处。 我还没有理由实际派生一个新的类,但实际上应该这样做。 本文讨论了在对话框类本身中处理这些问题的方法。 派生一个新类并添加此行为留作读者练习。

什么!?没有类似 GetCurSel() 的函数?

CListBox 控件和 CComboBox 控件都有一个函数来检索当前选中项目的索引号。 CListCtrl 没有,所以我使用以下方法。

int CMyDialog::GetSelectedItem()
{
    int nItem = -1;
    POSITION nPos = m_ctrlMyList.GetFirstSelectedItemPosition();
    if (nPos)
    {
        nItem = m_ctrlMyList.GetNextSelectedItem(nPos);
    }
    return nItem;
}

项目高亮显示的问题

好的,你有了你的列表控件,你点击一个项目,正如预期的那样,出现了一个高亮条。很好。 现在,如果你点击列表控件中最后一个项目下方的空白区域,会发生什么? 我告诉你发生了什么 - 高亮条消失了。 这都很好,但是如果你调用我上面给出的函数,它会返回什么索引号? 错了,它不是 -1(正如你可能期望的那样),而是最后一次高亮显示(或选中)项目的索引。 你如何解决它? 处理 OnClick... 和 OnRclick... 函数

void CMyDlg::OnClickList(NMHDR* pNMHDR, LRESULT* pResult) 
{
    NM_LISTVIEW* pNM = (NM_LISTVIEW*)pNMHDR;
    int nCount = m_ctrlList.GetItemCount();
    LVHITTESTINFO ht;
    ht.pt = pNM->ptAction;
    m_ctrlList.SubItemHitTest(&ht);
    if (ht.iItem < 0 || ht.iItem > nCount)
    {
        int nItem = GetSelectedItem();
        // re-establish the highlight bar on the last selected item 
        // (taking advantage of the control's bug)
        m_ctrlList.SetItemState(nItem, 
            LVIS_SELECTED, LVIS_SELECTED | LVIS_FOCUSED);
    }
    else
    {
        // highlight the item selected
        m_ctrlHostList.SetItemState(ht.iItem, 
            LVIS_SELECTED, LVIS_SELECTED | LVIS_FOCUSED);
    }
    *pResult = 0;
}

void CMyDlg::OnRclickList(NMHDR* pNMHDR, LRESULT* pResult) 
{
    NM_LISTVIEW* pNM = (NM_LISTVIEW*)pNMHDR;
    int nCount = m_ctrlList.GetItemCount();
    if (nCount > 0)
    {
        LVHITTESTINFO ht;
        ht.pt = pNM->ptAction;
        m_ctrlList.SubItemHitTest(&ht);
        if (ht.iItem < 0 || ht.iItem > nCount)
        {
            int nItem = GetSelectedItem();
            m_ctrlList.SetItemState(nItem, 
                LVIS_SELECTED, LVIS_SELECTED | LVIS_FOCUSED);
        }
        else
        {
            m_ctrlList.SetItemState(ht.iItem, 
                LVIS_SELECTED, LVIS_SELECTED | LVIS_FOCUSED);
        }
    }
    *pResult = 0;
}

玩得开心,记住,我只在报告模式下使用过这个。

© . All rights reserved.