First, it may NOT be possible. For example, if the list doesn't have enough items after your top index to fill the page.
As there is no direct way, you can count the number of items on the page, add that count to your index and call EnsureVisible()
. This will make your sure that your top is above visible page. The next EnsureVisible()
for your item will bring it into the view, at the top of the page. Of course, you would need to block updates to avoid jerking of the screen.
Example (updated by Vlad):
void CDlg::SetTopIndex(int top)
{
int bottom = min(top + m_List.GetCountPerPage(), m_List.GetItemCount() - 1);
m_List.SetRedraw(FALSE);
m_List.EnsureVisible(bottom, TRUE);
m_List.EnsureVisible(top, FALSE);
m_List.SetRedraw(TRUE);
}
LVM_ENSUREVISIBLE
message is a start. SetlParam
toFALSE
to make sure the item is entirely visible. But this just makes sure it is visible, it doesn't necessarily zoom it up to the top of the list. It's going to be rather difficult to do that, of course, depending on the size of the list view control and the number of items in it. – EditheLVM_ENSUREVISIBLE
is a start, but that just ensures performs a minimal scroll so that the selected item is visible, it will be either at the first line of at the last line depending on if the selected item was above or below the view.LVM_SETTOPINDEX
is again something that Microsoft forgot. – SinglemindedLVM_GETTOPINDEX
), if the desired item is above it you can just callLVM_ENSUREVISIBLE
, If its below, get the count of items within the current viewport (LVM_GETCOUNTPERPAGE
) then you can calculate the index of the item you need to use withLVM_ENSUREVISIBLE
to bring the desired item to the top(want_at_top_index + LVM_GETCOUNTPERPAGE) - 1
– Evette