- ベストアンサー
CTreeCtrlのHitTestメソッドについて
環境:WinXP VS2005 MFC使用 CTreeCtrlに階層のあるアイテムを複数個設定しています。 ノード開閉時にカーソル位置にあるアイテムをGetCorsorPos()+HitTest()関数を使用し、取得していました。これは正しいアイテムのハンドルが返ってきています。 ところが、ある程度ノードを開いていき、表示しきれなくなるとスクロールが表示されますが、一番下までスクロールしている状態だとアイテムがうまく取得できていないようです。 おそらく、GetCursorPosが画面上の相対座標を取得するのに対し、HitTestで設定するのはツリーコントロール自体の相対座標なので、スクロールしている分だけずれてしまっているのではないかと思っているのですが、スクロールしているサイズを取得する方法がわかりませんでした。ご存じの方いましたらご教授をお願いします。 ※ソース抜粋 void CTestTreeCtrl::OnTvnItemexpanded(NMHDR *pNMHDR, LRESULT *pResult) { CPoint point; GetCursorPos(&point); ScreenToClient(&point); // マウスカーソルの位置からアイテムのハンドルを取得する HTREEITEM hItem = HitTest(point); ・ ・ ・
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
yutyantyan さんが本当に取得したいのは "どれだけスクロールしたか" ではなくて "スクロールした状態でのツリーのアイテム" ですよね?? "ツリーのアイテムが選択された" ときには TVN_SELCHANGED イベントをキャッチすることができます. また,そのメッセージハンドラの中は以下のようになっています. //------------------------------------------------------------ LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR); // TODO: ここにコントロール通知ハンドラ コードを追加します。 *pResult = 0; //------------------------------------------------------------ この TODO の下で HTREEITEM hItem = pNMTreeView->itemNew.hItem; とすれば,選択したアイテムを取得できます. このようにすれば,スクロールした距離を取得する必要もなければ,マウスの座標から HitTest でアイテムを取得する必要もなくなります. スクロールしている距離を取得する方法の回答にはなっていませんが,この方法ではダメですか?
その他の回答 (1)
- Wr5
- ベストアンサー率53% (2173/4061)
動作検証している時間がありませんが… CTreeCtrl::GetFirstVisibleItem()でTreeViewの先頭に表示されているアイテムを取得、 CTreeCtrl::GetItemRect()で、そのアイテムの表示されているRECTを取得して、 RECT.leftとRECT.topをHitTestする際のPOINTに加算してみてはどうでしょうか? 先頭のアイテムが一部だけ表示されている状態の時にズレが出るような気もしますが……。
お礼
貴重なご意見ありがとうございます。 参考にさせていただきます。
お礼
なるほど。。。 今までスクロール周りの制御しか見ていなかったので、イベントそのものを変えるという発想が出てきませんでした。 大変参考になりました。さっそく試してみます。 貴重なご意見ありがとうございました。