リストビューのスクロール制御

[戻る]
アレン 2008/04/21(月) 16:36:25
現在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);

アレン 2008/04/23(水) 14:09:07
横位置に関して


//スクロール横位置取得
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();

とやってみたのですが、こちらもダメでした。

アレン 2008/04/23(水) 15:49:48
縦位置に関しては

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];

}

gak 2008/04/23(水) 16:43:04
> 横位置に関して
LVM_SCROLL を使えば良いかと

const int cx = Px - ::GetScrollPos((HWND)listView->Handle.ToInt32(), SB_HORZ);
::SendMwssage((HWND)listView->Handle.ToInt32(), LVM_SCROLL, cx, 0);

アレン 2008/04/24(木) 11:35:57
[[解決]]
gakさんの提示していただいたLVM_SCROLLで無事横位置の設定もうまくいきました。

なかなか情報がみつからない状態でしたので、
大変助かりました。

本当にありがとうございました。

/******************以下 修正ソース ***************************/

//スクロール横位置取得
Px = GetScrollPos((HWND)listView->Handle.ToPointer(), SB_HORZ);

  中略

(System::IntPtr)::SendMessage((HWND)listView->Handle.ToPointer(),
                               LVM_SCROLL, Px, 0);

古いスレッドには追加発言できません。