現在VS2005 CLI環境で開発しております。
リストビューのスクロール状態を保持して、
リストの更新後にスクロール状態を横位置は復元、
縦位置は任意の場所に移動させたいのですが、
どちらもうまくいきません。
以下に示すソースのように行ったのですが、
・横位置はスクロール位置は移動したのですが、
リストビューの中身が移動しない。
・縦位置は、EnsureVisibleの利用で可視できる場所まではスクロールが移動するが、
一番下になってしまうので、もう少し真中にもってくるなど制御ができないか?
という状態です。
何かわかる方がいましたら、
ご教授していただけませんでしょうか?
宜しくお願いいたします。
/***************以下 ソース ************************/
String ^ID;
int Px, TopViewID, SelID, sa;
//スクロール横位置取得
Px = GetScrollPos((HWND)listView->Handle.ToPointer(), SB_HORZ);
TopViewID = -1;
SelID = -1;
ID = ";
sa = -1;
if (listView->SelectedItems->Count > 0) {
TopViewID = listView->TopItem->Index;
SelID = listView->SelectedItems[0]->Index; // マルチセレクトでないので一つ目
sa = TopViewID - SelID; // 選択箇所と表示先頭の差
ID = listView->SelectedItems[0]->SubItems[7]->Text; // 一意のキー
}
this->listView->BeginUpdate();
//リストの更新
for each( アイテム情報 ){
// 一意のキーと一致したアイテムの場所を取得
if ((ID != ") && (ID == sw_item->uID))
SelID = i;
}
if (TopViewID != -1) {
//選択位置とフォーカス設定
this->listView->Focus();
this->listView->Items[SelID]->Selected = true;
this->listView->Items[SelID]->Focused = true;
// TopItemのIndexが設定できればよかったのだけど、
// IndexはSetがないみたいなのでできない
//
//TopViewID = SelID + sa;
//if (TopViewID < 0)
// TopViewID = 0;
//this->listView->TopItem->Index = TopViewID;
// 仕方ないので以下の関数を利用したが、一番下にみえるだけなので、
// もう少し真中に持ってくるとかできないのか?
this->listView->EnsureVisible(TopViewID);
}
this->listView->EndUpdate();
//横スクロールバー位置セット
SetScrollPos((HWND)listView->Handle.ToPointer(), SB_HORZ, Px, TRUE);
横位置に関して
//スクロール横位置取得
Px = GetScrollPos((HWND)listView->Handle.ToPointer(), SB_HORZ);
以下省略
ScrollWindow((HWND)listView->Handle.ToPointer(), -Px, 0, NULL, NULL);
SetScrollPos((HWND)listView->Handle.ToPointer(), SB_HORZ, Px, TRUE);
listView->Update();
としてみたがダメでした。
次に
(System::IntPtr)::SendMessage((HWND)listView->Handle.ToPointer(),
WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, Px), 0);
listView->Update();
とやってみたのですが、こちらもダメでした。
縦位置に関しては
TopItem->Indexはリードのみですが、
だったらItemごと渡してしまえばすむ話でした。
あとは、横位置…
/***************以下 修正ソース ************************/
if (listView->SelectedItems->Count > 0) {
TopViewID = listView->TopItem->Index;
SelID = listView->SelectedItems[0]->Index; // マルチセレクトでないので一つ目
sa = TopViewID - SelID; // 選択箇所と表示先頭の差
ID = listView->SelectedItems[0]->SubItems[7]->Text; // 一意のキー
}
中略
if (TopViewID != -1) {
//選択位置とフォーカス設定
this->listView->Focus();
this->listView->Items[SelID]->Selected = true;
this->listView->Items[SelID]->Focused = true;
TopViewID = SelID + sa;
if (TopViewID < 0)
TopViewID = 0;
// これはReadOnlyだからSetできない
//this->listView->TopItem->Index = TopViewID;
// だったらアイテムごと渡せばよい
this->listView->TopItem = this->ListView->Items[TopViewID];
}
> 横位置に関して
LVM_SCROLL を使えば良いかと
const int cx = Px - ::GetScrollPos((HWND)listView->Handle.ToInt32(), SB_HORZ);
::SendMwssage((HWND)listView->Handle.ToInt32(), LVM_SCROLL, cx, 0);
gakさんの提示していただいたLVM_SCROLLで無事横位置の設定もうまくいきました。
なかなか情報がみつからない状態でしたので、
大変助かりました。
本当にありがとうございました。
/***************以下 修正ソース ************************/
//スクロール横位置取得
Px = GetScrollPos((HWND)listView->Handle.ToPointer(), SB_HORZ);
中略
(System::IntPtr)::SendMessage((HWND)listView->Handle.ToPointer(),
LVM_SCROLL, Px, 0);