CTreeCtrlのスクロールについて

[戻る]
オクラ 2008/02/15(金) 17:07:02
VC++7.0 MFCを使用して開発を行っています。
CTreeCtrlに対してアイテムを約80000件InsertItemメソッドにて登録を行い、スクロー
ルをさせたのですが65535行目以降のスクロールがされません。

CTreeCtrlを派生させてOnVScrooイベントを取得しその関数内で65535行目以降の
HTREEITEMを取得しSelectItemメソッドを行うと65535以降は先頭から再度表示しなおさ
れてしまいました。

何か制限等はあるのでしょうか?また解決策としてどのような方法があるのかわかる方
がいらしたらご教授お願いします。

SSH 2008/02/15(金) 20:59:21
OnVScroll の引数で与えられるスクロールポジションを使用しているのであれば、
その引数の上限は0xFFFFまでと制限されています。
これは、GetScrollPosを使用してスクロールポジションを再取得する事で回避できま
す。

オクラ 2008/02/18(月) 11:12:40
SSH様
回答ありがとうございます。

void CTreeWnd::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    // TODO : ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼
び出します。


    nPos = GetScrollPos(SB_VERT);
    CTreeCtrl::OnVScroll(nSBCode, nPos, pScrollBar);

}

上記のようにしてみたのですが、
スクロールポジションが65535行のときに下スクロールさせてもnPosは65535で変わりま
せんでした。

やり方が間違えていたらご指摘お願いします。
GetScrollPosの使用例を具体的に教えていただけると助かります。
よろしくお願いいたします。

シャノン 2008/02/18(月) 11:31:25
OnVScroll に 65536 以上の数値を渡しても無理でしょう。
というかそれ以前に、

> この関数に渡されるパラメータの値は、フレームワークがメッセージ受信時に
> 受け取ったパラメータの値に基づいています。この関数の基本クラスの実装を
> 呼び出した場合は、関数に渡したパラメータではなく、メッセージと共に渡された
> パラメータ自体が使用されます。

とか書いてあるし。
http://msdn2.microsoft.com/ja-jp/library/fhfk142k(VS.80).aspx

というわけで、CTreeView::OnVScroll を呼ばずに SetScrollPos するのが正解なんじゃ
ないかと。

オクラ 2008/02/18(月) 14:04:36
シャロン様
回答ありがとうございます。

OnVScrollを呼ばずにSetScrollPosでスクロール位置を設定したのですが
スクロールは65535以上サムが移動できたのですが
スクロールの動作に対してツリー表示部分が動作しなくなってしまいました。

そこで

hItemS = GetRootItem();
for(int i=0;i < 70000;i++)        
{    
    hItemS =GetNextItem(hItemS, TVGN_NEXT);
    if(i == 66000)
    {
        break;
         }    
}

BOOL ret = SelectItem(hItemS);

でツリー表示部をスクロール移動させたのですが
今度はSetScrollPosで設定したスクロール位置がSelectItemで上書きされてしまい
結局65535までしかスクロールしなくなってしまいます。

ので、ツリー表示部をスクロールに依存せずに表示できれば可能なのではないかと
考えているのですがそのような方法で何かないでしょうか。
よろしくお願いします。

シャノン 2008/02/18(月) 14:51:40
うーん…
そもそも、どういうことを実現したいんでしょうか?
単に 65,535 個を上回るアイテムを追加しただけで、それ以降が表示できなくなる?
# 試せていません。
# 80,000 個アイテムを追加するループで CPU 使用率が 100% になって凍ったorz

オクラ 2008/02/18(月) 16:46:03
実現したいことは現状では単純に65535個以上のアイテムを追加したいということです。

65535以上のアイテムを入れると
1行スクロールと1ページスクロールを行うと65535行目で止まって
それ以降スクロールできなくなります。
またドラッグして65535行目以降に行くと65536行目以降が0からの表示になって
クリックを離すとスクロール位置は元の0からの位置に戻ってしまいます。
例えば70000行目を表示しようとすると
4465行目(70000 - 65535)
に移動してしまいます。

SSH 2008/02/18(月) 17:59:25
試しに組んでみたところ、
GetScrollInfoで得られる情報からしておかしくなっているので、 
CTreeCtrlを使用する限りはこの問題をクリアするのは難しそうに感じました。


どういう仕様なのかわかりませんが、私なら以下の回避作を検討します。

1、CTreeCtrlを使用せず、自分で一からツリーコントロールを作成する
2、一つのCTreeCtrlに追加できるアイテムの上限を65535に制限して、他のコントロー
ルからCTreeCtrlの内容を切り替えられるようにする(もしくは複数のCTreeCtrlを生成す
る)。

オクラ 2008/02/19(火) 15:42:21
[[解決]]
 > 1、CTreeCtrlを使用せず、自分で一からツリーコントロールを作成する

その方法がベストかもしれません。
とりあえず時間も余りないものでCTreeCtrlは使用しないで市販のツリーコントロールを
使ってやってみようと思っています。

ご回答下さいました皆様どうもありがとうございました。
だいぶ煮詰まっていたのでとても助かりました。

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