Announcement

Collapse
No announcement yet.

How to go up 1 node in a Tree?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Michael Mattias
    replied
    Have not tried this myself but I think it will work...

    Simulate an "up-arrow" or "down-arrow" keypress. When I was writing my own treeview-like control, I had to emulate the keyboard action.

    Up/Down arrow go, well, "up and down." The left and right arrows expand/collapse the current node.

    IIRC that has the benefit of automatically scrolling the 'target' node into view.

    Worth a try perhaps.

    MCM

    Leave a comment:


  • colin glenn
    replied
    I think a better term for that would be "exposed" over it being "visible", visible implies that the user can see it while exposed would indicate that the node's parent has expanded its children and they're now "available" to be "seen" if the user themselves was to scroll to the location of interest.

    Leave a comment:


  • Michael Mattias
    replied
    No, you are right.. "visible" is, in context, ambiguous.

    I was sure you meant "you can see it doing no more than scrolling vertically."

    But you might have meant, "You can see it RIGHT NOW without doing anything."

    Is the parent of the node currently at the top of the client area "visible?" Well, if you scroll it is, but if you don't it isn't.

    Leave a comment:


  • Gary Beene
    replied
    Michael,

    At first, I thought your comment was all wrong - because I thought "visible" meant that a node could be currently seen within the client area of the control.

    But, after your comment, I tested the code and sure enough - it will walk through any node that can be seen by scrolling, regardless of whether it is visible in the client area. As long as its parent is expanded, a child node fits the bill of "visible" as far as tvm_getitem is concerned.

    I was too literal on interpreting the use of "visible" in the documentation.

    Thanks for the clarification.

    Leave a comment:


  • Dominic Mitchell
    replied
    I can use SendMessage with %TVM_PreviousVisible and walk up a tree without having to
    go down, but it makes the starting node visible and will only move upwards to visible nodes
    I don't see this method as a solution, because have you tried it with hundreds of nodes, or nodes
    that are deeply nested, or with a large number of collapsed nodes. Even using WM_SETREDRAW would
    not eliminate flickering.

    If you do not want to walk up and down, you can maintain a linked-list of the items in the control, or
    roll your own treeview control.

    Leave a comment:


  • Michael Mattias
    replied
    Since all siblings are visible, or all siblings ain't.....

    Given: "hItem of interest"
    GetParent of hitem
    Get Grandparent of hitem (Parent of parent). If not expanded, parent is not visible.

    MCM

    Leave a comment:


  • Gary Beene
    replied
    Hi Dominic,

    I can use SendMessage with %TVM_PreviousVisible and walk up a tree without having to go down, but it makes the starting node visible and will only move upwards to visible nodes.

    Since it skips over nodes not visible, I'd have to expand everything under the parent node of the starting node. That would work but I simply want the ID of the 1-up node, not to actually have it visible.

    I can get what I want by expanding, then collapsing the nodes but there'd be some small amount of flicker involved. (I haven't tested to see how much is involved).

    Here's the useful code.

    Code:
           Treeview Get Select Cb.Hndl, %ID_TreeView To hNode         'hNode is currently selected node
           Control Send Cb.Hndl, %ID_TreeView, %TVM_GetNextItem, %TVGN_PreviousVisible, hNode To hUpNode
           Treeview Select Cb.Hndl, %ID_TreeView, hUpNode
    So, there are at least 2 solutions to getting the 1-up node, but neither was as "elegant" as I wanted.

    For now, I'll just go with the up then down approach.

    Here's a compilable version using the 3 lines above.

    Code:
     #Compile Exe
     #Dim All
    #Include "Win32api.inc"
    #Include "commctrl.inc"
     %ID_TreeView = 100
     Function PBMain() As Long
        Local hDlg As Dword, hItem As Dword
        Local hTemp As Dword, hTemp2 As Dword, hTemp3 As Dword
        Dialog New Pixels, 0, "TreeView",200,200,155,250, %WS_SysMenu, 0 To hDlg
        Control Add Treeview, hDlg, 100, "", 10,10,130,50 '200
        Treeview Insert Item hDlg, 100, 0, %TVI_Last, 2,2,"Top" To hItem
    
        Treeview Insert Item hDlg, 100, hItem, %TVI_Last, 2,4,"Mother" To hTemp
           Treeview Insert Item hDlg, 100, hTemp, %TVI_Last, 2,4,"Dan" To hTemp2
           Treeview Insert Item hDlg, 100, hTemp, %TVI_Last, 1,4,"Bob" To hTemp3
              Treeview Insert Item hDlg, 100, hTemp3, %TVI_Last, 2,4,"Foot" To hTemp2
              Treeview Insert Item hDlg, 100, hTemp3, %TVI_Last, 1,4,"Arm" To hTemp2
    
        Treeview Insert Item hDlg, 100, hItem, %TVI_Last, 1,4,"Father" To hTemp
           Treeview Insert Item hDlg, 100, hTemp, %TVI_Last, 2,4,"Helen" To hTemp2
           Treeview Insert Item hDlg, 100, hTemp, %TVI_Last, 1,4,"Any" To hTemp3
              Treeview Insert Item hDlg, 100, hTemp3, %TVI_Last, 2,4,"Leg" To hTemp2
              Treeview Insert Item hDlg, 100, hTemp3, %TVI_Last, 1,4,"Finger" To hTemp2
        Control Add Button, hDlg, 200, "Walk", 10,220,40,20
    
        Dialog Show Modal hDlg Call DlgProc
     End Function
    
    
     CallBack Function DlgProc() As Long
     Dim hTreeView As Dword, hNode As Dword, hUpNode As Dword
        If Cb.Msg = %WM_Command And Cb.Ctl = 200 Then
           Treeview Get Select Cb.Hndl, %ID_TreeView To hNode         'hNode is currently selected node
           Control Send Cb.Hndl, %ID_TreeView, %TVM_GetNextItem, %TVGN_PreviousVisible, hNode To hUpNode
           Treeview Select Cb.Hndl, %ID_TreeView, hUpNode
        End If
     End Function

    Leave a comment:


  • Dominic Mitchell
    replied
    Your "brute" force method(walking up and then down) is the only way. A treeview linked-list has next
    and previous sibling properties, but no left and right item properties. The treeview displays items
    as an indented outline, therefore, by left I mean the item that appears immediately before the item
    of interest, and right is the item that appears immediately after the item of interest.

    Leave a comment:


  • Gary Beene
    replied
    Michael,

    Thanks for the response, but I don't think we're singing from the same page in the hymn book.

    As I mentioned in my post, GetParent will work just fine but it puts me above the node of interest and I have to travel downward.

    That's what I'd like to avoid. I already know how to travel down. I was trying to figure out a way to travel up.

    The item's list of child items is currently expanded; that is, the child items are visible. This value applies only to parent items.
    Also, to your comment, just because an item is expanded doesn't mean it is visible - unless you are saying that GetItem only returns TVIS_Expanded if the node is visible, or that using GetItem forces the item to be visible? And even if both of those are true for the starting node or its parent, the 1-up node is not necessarily visible.

    The 1-up node directly above the starting node may be several levels deeper than the parent or sibling (GetParent/GetPreious) of the starting node. So selecting, then expanding the starting node or its parent doesn't guarantee that the 1-up node will be visible.

    Perhaps I don't quite understand your hint?

    Leave a comment:


  • Michael Mattias
    replied
    There's also the deviously-named "treeview_getparent" function which may be of some use.....

    Leave a comment:


  • Michael Mattias
    replied
    Today's Hint.......

    Treeview_GetItem .....

    Code:
    struct tagTVITEMEX {
        UINT mask;
        HTREEITEM hItem;
    [COLOR="Red"][b]    UINT state;[/b][/COLOR]
        UINT stateMask;
        LPTSTR pszText;
        int cchTextMax;
        int iImage;
        int iSelectedImage;
        int cChildren;
        LPARAM lParam;
        int iIntegral;
    } TVITEMEX, *LPTVITEMEX;
    ...
    TVIS_EXPANDED
    The item's list of child items is currently expanded; that is, the child items are visible. This value applies only to parent items.
    MCM

    Leave a comment:


  • Gary Beene
    started a topic How to go up 1 node in a Tree?

    How to go up 1 node in a Tree?

    I'd like to get the handle of the first node above a specified node. The two nodes are not visible, nor selected.

    I could get use Get Previous or Get Parent to get a node higher up the Tree, and then walk downward (here's my latest code for downward tree walking), but I haven't figured how to modify the approach to walk up a tree. Walking down the tree would work, but I was looking for a less "brute force" way of doing it.

    Code:
    Sub TreeWalk2(ByVal hWnd As Dword, ByVal hNode As Dword)
       Dim iReturn As Dword, hSibling As Dword
       Do
            Treeview Get Child hWnd, %ID_Treeview, hNode To iReturn                    'get child (1st choice)
            If iReturn = 0 Then Treeview Get Next hWnd, 100, hNode To iReturn 'or sibling (2nd choice)
            If iReturn = 0 Then                                               'no child or sibling
                Do      'get sibling of first parent with sibling
                   Treeview Get Parent hWnd, %ID_TreeView, hNode To hNode            'parent
                   Treeview Get Next hWnd, %ID_TreeView, hNode To iReturn            'sibling child of parent
                Loop Until iReturn Or (hNode = 0)  'stop when find sibling of parent with sibling, or no more choices
            End If
            hNode = iReturn    'possible values: 0, zero (no parent/no sibling), <>0 (parent or sibling)
            Sleep 250 : If iReturn Then Treeview Select hWnd, %ID_TreeView, hNode
       Loop While hNode
    End Sub
    Here's the description of treewalking definition that I'm using.
    Code:
    1
      2
         3
         4 
         5
      6 
         7
         8 
         9 
     10 
         11
            12
            13
    Using the TVM_GetNextItem message, with TGVN_PreviousVisible is close to what I want, but it only works if the desired node is visible, and I can't force the node to be visible unless I know the node. Plus, I really don't want the Tree to be jumping around.

    Any thoughts?
Working...
X