クリア前に一番上のアイテムをセーブして、
FSaveTop := ListView1.TopItem;
更新後、リストビューをスクロールして、保存された一番上のアイテムの 'y' 位置が 0 (+ ヘッダーの高さ) になるようにします。
var
R: TRect;
begin
if Assigned(FSaveTop) then begin
// account for header height
GetWindowRect(ListView_GetHeader(ListView1.Handle), R);
ListView1.Scroll(0, FSaveTop.Position.Y - (R.Bottom - R.Top));
end;
end;
実際には、リストビューを再作成しているため、参照を保存するのではなく、一番上にしたいアイテムを見つけるメカニズムを考案する必要があります。
SetScrollInfo
のような関数SetScrollPos
はコントロールのクライアント領域を更新しないため、「トップ項目」を介してスクロール位置を変更したくない場合は、リストをクリアする前GetScrollInfo
に a の「nPos」を取得し、それを送信することができます。入力後に「SB_LINEDOWN」を含むTScrollInfo
多くのメッセージ。WM_VSCROLL
スクロール位置を保存:
var
FPos: Integer;
SInfo: TScrollInfo;
begin
SInfo.cbSize := SizeOf(SInfo);
SInfo.fMask := SIF_ALL;
GetScrollInfo(ListView1.Handle, SB_VERT, SInfo);
FPos := SInfo.nPos;
...
データを入力したら、スクロールします (スクロール位置が 0 であると仮定):
var
R: TRect;
begin
...
R := ListView1.Items[0].DisplayRect(drBounds);
ListView1.Scroll(0, FPos * (R.Bottom - R.Top));
また、
var
i: Integer;
begin
...
for i := 1 to FPos do
SendMessage(ListView1.Handle, WM_VSCROLL, SB_LINEDOWN, 0);