CListCtrl:如何保持水平滚动位置?

时间:2012-06-07 23:17:01

标签: winapi mfc scroll clistctrl

如何保持CListCtrl的水平滚动条位置?我定期转储并重新填充列表控件的内容,因此没有明确记住旧位置并恢复它,滚动就会回到左上角。

我早些时候问了一个相关的问题CListCtrl: How to maintain scroll position?,但当时我只对垂直滚动位置感兴趣并且提供的答案解决了这个问题。但是,现在我想记住并恢复水平滚动位置(以及垂直滚动)。

1 个答案:

答案 0 :(得分:1)

首先,您可能会想到更简单。您必须在重新填充列表之前以及在重新填充强制列表控件之后保存位置以更新新内容。

此外,您可能会考虑到新内容可能包含不同数量的事实,因此您必须设置相对于最大滚动位置的位置。

示例代码如下:

    SCROLLINFO sbiBefore = { sizeof(SCROLLINFO) };
    SCROLLINFO sbiAfter = { sizeof(SCROLLINFO) };

    // get scroll info before
    sbiBefore.fMask = SIF_ALL;
    m_List.GetScrollInfo(SB_HORZ, &sbiBefore);

    RenewContents();

    // force control to redraw
    int iCount = m_List.GetItemCount();
    m_List.RedrawItems(0, iCount);

    // get the scroll info after
    sbiAfter.fMask = SIF_ALL;
    m_List.GetScrollInfo(SB_HORZ, &sbiAfter);

    double dRatio = (double)sbiAfter.nMax / sbiBefore.nMax;

    // compute relative new position
    sbiAfter.fMask = SIF_POS;
    sbiAfter.nPos = dRatio * sbiBefore.nPos;

    // set new position
    BOOL bSet = m_List.SetScrollInfo(SB_HORZ, &sbiAfter);

我确信你可以用同样的方式处理垂直滚动。 在您提到的帖子中,EnsureVisible用于不必要地强制更新,因为您有更合适的方法。 此外,如果最后一项已经可见,则使用EnsureVisible将无效。