tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルTreeView MouseMoveで、当該ノードでの x ,y 位置
記事No14912
投稿日: 2010/09/08(Wed) 12:41
投稿者ima
お世話になります。  ( WinXP VB6 sp6 )

ツリービューのノード間に線を引くには
http://hpcgi1.nifty.com/MADIA/VBBBS2/wwwlng.cgi?print+200506/05060109.txt

に有るようなことをコーディングしました。

下記手法では、HitTest メソッドでノードを特定するため、MouseMoveで
対象ノード内のどの部分(上とか下とか)を動かしても、そのノードの下に線を引く事になります。

Private Sub TreeView1_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single) にて、

    TreeView1.HitTest(x, y).Selected = True
    hItem = SendMessage(TreeView1.hwnd, TVM_GETNEXTITEM, TVGN_CARET, ByVal 0)
    lpData(0) = hItem
    Call SendMessage(TreeView1.hwnd, TVM_GETITEMRECT, True, lpData(0))
    r.Left = TreeView1.Left + lpData(0)
    r.Top = TreeView1.Top + lpData(1)
    r.Right = TreeView1.Left + lpData(2)
    r.Bottom = TreeView1.Top + lpData(3)
    With picSplitter
        .Top = r.Bottom + 1
        .Left = r.Left
        .Width = r.Right - r.Left
        .Visible = True
    End With

それを出来れば、
対象ノード内の上半分の領域では、対象ノード内の上に線を描画し、
対象ノード内の下半分の領域では、対象ノード内の下に線を描画する。

と言ったことを出来ればと考えています。

⇒ 最終的な目的は、FirstSiblingノードの上にも線を引き、対象ノードを先頭ノード
の上に Drag & Drop で移動を行いたいのです。

つまり、MouseMoveイベントでの x ,y 位置をTreeView基準でなく、ノード基準で
判断できないか? 或いは、当該ノードの上半分にいるのか下半分にいるのかを
判断したいのです。

宜しくお願いします。

[ツリー表示へ]
タイトルRe: TreeView MouseMoveで、当該ノードでの x ,y 位置
記事No14913
投稿日: 2010/09/08(Wed) 14:31
投稿者魔界の仮面弁士
フォントにもよりますが、ノードの高さって、数十ピクセル程度ですよね。

マウス位置を基準として、その y 座標を少しずつ変更しながら
HitTest なり TVM_HITTEST なりを繰り返していき、別ノードが
参照されるまでの座標を測定してみれば、現在のマウス位置が
そのノード内の上半分にあるのか下半分にあるのかがわかるかも。

[ツリー表示へ]
タイトルRe^2: TreeView MouseMoveで、当該ノードでの x ,y 位置
記事No14914
投稿日: 2010/09/09(Thu) 08:45
投稿者ima
魔界の仮面弁士さん

またも的確なアドバイスを戴き、解決しました。

'マウスの位置が対象ノードの上半分か下半分かの判断
Private Function UpperLowerTest(SelNode As Node, ByVal x As Single, ByVal y As Single) As Boolean
Dim oNode As Node, Un As Long, Ln As Long, n As Long
    n = y
    Do
        n = n - Screen.TwipsPerPixelY   'ピクセル単位でLoop回数抑える
        Un = Un + 1
        Set oNode = TreeView1.HitTest(x, n)
        If oNode Is Nothing Then Exit Do
    Loop While SelNode Is oNode
    n = y
    Do
        n = n + Screen.TwipsPerPixelY
        Ln = Ln + 1
        Set oNode = TreeView1.HitTest(x, n)
        If oNode Is Nothing Then Exit Do
    Loop While SelNode Is oNode
    If Un < Ln Then
        UpperLowerTest = True
    Else
        UpperLowerTest = False
    End If
End Function

どうも有り難うございました。

[ツリー表示へ]
タイトルRe^3: TreeView MouseMoveで、当該ノードでの x ,y 位置
記事No14918
投稿日: 2010/09/09(Thu) 19:27
投稿者魔界の仮面弁士
> n = n - 15  'ピクセル単位でLoop回数抑える
15 とは限りませんので、Screen.TwipsPerPixelY を使う事をおすすめします。

> Loop While SelNode = oNode
= 演算子を使って比較してはマズイと思いますよ。

上記の場合、SelNode.[_ObjectDefault] すなわち
 Loop While SelNode.Text = oNode.Text
のような意味になってしまいますので、たとえば
同名ノードが並んでいるような場合に正しく処理できなくなります。

代わりに、Is 演算子を利用してみて下さい。

[ツリー表示へ]
タイトルRe^4: TreeView MouseMoveで、当該ノードでの x ,y 位置
記事No14922
投稿日: 2010/09/10(Fri) 20:41
投稿者ima
魔界の仮面弁士さん、今回も添削頂き恐縮です。

> > n = n - 15  'ピクセル単位でLoop回数抑える
> 15 とは限りませんので、Screen.TwipsPerPixelY を使う事をおすすめします。

→ これは個人的ツールと言うことで確信犯的に簡易記載していますが、
 変な癖や、後から参考にされる方の事を考えればマズイですね。
 やはり基本に忠実が何よりですね。

> 上記の場合、SelNode.[_ObjectDefault] すなわち
>  Loop While SelNode.Text = oNode.Text
> のような意味になってしまいますので、たとえば
> 同名ノードが並んでいるような場合に正しく処理できなくなります。
>
> 代わりに、Is 演算子を利用してみて下さい。

→ 納得です。あとで変な不具合としてバグ候補となるのは確かにダメですね。
 勉強になりました。

どうもありがとうございました。
♪ 以前の投稿も修正しておきました。

[ツリー表示へ]