问题
How can I maintain the horizontal scroll bar position of a CListCtrl? I periodically dump and repopulate the contents of the list control so without explicitly remembering the old position and restoring it the scroll just goes back to the top left.
I asked a related question, CListCtrl: How to maintain scroll position?, earlier but at the time I was only interested in vertical scroll position and the answer supplied solved that. However, now I want to remember and restore the horizontal scroll position (as well the vertical scroll).
回答1:
First of all, it is simpler you may think. You have to save position before repopulating list and after repopulating force list control to update new content.
Also, you may take under consideration the fact that new content may have different number of items, hence you will have to set position relative to the max scroll position.
The sample code follows:
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);
I am sure that you can handle vertical scroll in the same manner. In the post you mentioned, EnsureVisible is used to force update unnecessarily, since you have more proper way of doing it. Also, using EnsureVisible would not work if last item is visible already.
来源:https://stackoverflow.com/questions/10941173/clistctrl-how-to-maintain-horizontal-scroll-position