如何保持 CListCtrl 的水平滚动条位置?我定期转储并重新填充列表控件的内容,因此在没有明确记住旧位置并恢复它的情况下,滚动只是回到左上角。
我问了一个相关的问题,CListCtrl:如何保持滚动位置?,较早但当时我只对垂直滚动位置感兴趣,提供的答案解决了这个问题。但是,现在我想记住并恢复水平滚动位置(以及垂直滚动)。
如何保持 CListCtrl 的水平滚动条位置?我定期转储并重新填充列表控件的内容,因此在没有明确记住旧位置并恢复它的情况下,滚动只是回到左上角。
我问了一个相关的问题,CListCtrl:如何保持滚动位置?,较早但当时我只对垂直滚动位置感兴趣,提供的答案解决了这个问题。但是,现在我想记住并恢复水平滚动位置(以及垂直滚动)。
首先,您可能认为它更简单。您必须在重新填充列表之前和重新填充强制列表控件之后保存位置以更新新内容。
此外,您可能会考虑到新内容可能具有不同数量的项目这一事实,因此您必须设置相对于最大滚动位置的位置。
示例代码如下:
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 将不起作用。