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 の使用は機能しません。