Wiki Home

Tree View


Namespace: SoftwareEng
The Tree View is one of the ActiveX controls that ships with Visual Studio.

There are two examples in the solutions.app that ships with VFP under:
  • ActiveX
  • ActiveX controls
  • Add and remove items in a treeview control
  • Provide a hierarchical display of items

  • Three excellent Treeview downloads, excellent for learning and mastering this control:
    Datatree on the Universal ThreadOffsite link to http://www.universalthread.com., File #9281, by MilesGordon
    Ndragger on the Universal ThreadOffsite link to http://www.universalthread.com., File #9321, by RenatoDeGiovanni
    Any member, pay or not, can download from the UT
    TreeView101 http://www.geocities.com/df_foxpro/qgen018.htm
    Very good sample with clases.vcx included at:
    arbol.zip http://documentos.arq.com.mx/Detalles/1021.html by Eduardo Reyes
    A white paper and sample code on the Tree View (and several other ActiveX controls) is available on the Technical Papers page http://www.stonefield.com/techpap.aspx of the Stone Field Systems Group Web site.
    In the ActiveX Controls subindex there's the example of the treeview

    In the solution application installed with VFP samples, there's a useful
    treeview sample
    from the command window run:
    DO HOME(2) + '\Solution\Solution.App'


    Simple Tree View example:
    * TreeView101.prg
    * creates a treeview
    * By CarlKarsten
    
    RELEASE goOtForm
    PUBLIC goOtForm
    
    * Create a form with a treeview on it
    goOtForm = CREATEOBJECT( "cForm" )
    
    * do some things to the treeview
    * Add the first node (aka the Root)
    goOtForm.tree1.Nodes.Add( , , "A1", "Hello" )
    
    * Add a child, under the Root (4)
    loNode = goOtForm.tree1.Nodes.item["A1"]
    goOtForm.tree1.Nodes.Add( loNode, 4, "A2", "World" )
    
    * Make the A2 node visible
    goOtForm.tree1.Nodes.item["A2"].EnsureVisible()
    
    * Add 20 more nodes under A2
    loNode = goOtForm.tree1.Nodes.item["A2"]
    For lnI = 1 to 20
    	lcKey = "B" + Transform(lnI)
    	goOtForm.tree1.Nodes.Add( loNode, 4, lcKey, "Moon " + Transform(lnI) )
    endfor
    
    * Expand the A2 subtree (scrools the A1 off the top)
    goOtForm.tree1.Nodes.item["A2"].Expanded = .t.
    
    * Make the A1 node visible again
    loNode = goOtForm.tree1.Nodes.item["A1"].EnsureVisible()
    
    Return
    
    
    DEFINE CLASS cForm as Form
    
    	PROCEDURE init( toBO )
    
    		WITH this
    			
    			.show()
    			
    			.AddObject('cmdCancel', 'cCancel' )
    			.cmdCancel.visible = .t.
    			
    			.AddObject('tree1', 'olecontrol', 'COMCtl.treectrl')
    			WITH .tree1
    				.visible = .t.
    				.height = thisform.height - 35
    				.width = thisform.width - 20
    			ENDWITH
    		ENDWITH
    
    		RETURN
    
    	endproc
    	
    ENDDEFINE
    	
    DEFINE CLASS cCancel as CommandButton
    	CANCEL = .t.
    	caption = "Cancel"
    	PROCEDURE init
    		this.Height = 25
    		this.Top = thisform.height - this.Height - 5
    		this.left = thisform.width - this.Width - 5
    	endproc
    	PROCEDURE click
    		thisform.release
    	ENDPROC
    ENDDEFINE
    


    some useful tips:
    * Assign an ImageList to the treeview
    OleTree.ImageList = OleImagesList.Object
    
    * Load a picture in the ImageList and set an alias for the picture
    strImgKey = "MyImageCaption" && sets an alias for the image
    objImage = OleImagesList.ListImages.Add(, , LoadPicture(strPath)) && Load an icon and return the ListImage Object
    objImage.Key = strImgKey
    ImageListIndex = OleImagesList.ListImages(strImgKey).index
    
    * Adding Nodes to the Treeview
    strNodeIndex = "_1"
    strText = "Parent"
    oleTree.Nodes.add(,,strNodeIndex,strText, ImageListIndex) && adds a Top
    Level Node
    strParentNodeIndex = "_1"
    strNodeIndex = "_2"
    strText = "Child"
    oleTree.Nodes.add(strParentNodeIndex, 4, strNodeIndex, strText,
    ImageListIndex) && adds a child node
    


    MarcoRoello

    * Icons for Imagelist
    Provide the icons set in the imagelist physically when distributing, do not add these icons to the project (included or excluded), others were lucky, but as I had not found this written anywhere I had a tough time to figure out this. Bhavbhuti Nathwani
    Fox Talk June '97 and June '98 issues both contain invaluable articles by Doug Hennig documenting use of the Tree View. The earlier article is the one mentioned above on the Stonefield site, and offers basic information on the control's behavior.

    The more recent article describes the need for runtime loading of this and other ActiveX controls, rather than static inclusion at design time, and presents techniques for doing so.

    Notes on Using Tree View


    Once you figure out all these vagaries, OLEDragAndDrop is really great! - ?wgcs

    One person's report:
    When dragging the mouse over the tree i receve Type mismatch error on THIS.DropHighlight = loNode
    So can someone review the code/instructions? I see a few differencec between this and the code just below.
    Here is a prg version of the above treview drag/drop. Notice the this.object.oledropmode = 1 line. Objects in an OLE container need to be referenced via the .object property of the container. The property sheet kind of mixes the container and the contained objects properties (or something like that.) -- ?CFK
    RELEASE goForm
    PUBLIC goForm as mytreeform OF ddtree2.prg
    
    goForm = CREATEOBJECT( "myTreeForm" )
    goForm.show
    
    RETURN
    
    DEFINE CLASS myTreeForm  AS form
    
      Top = 0
      Left = 0
      Height = 253
      Width = 375
      DoCreate = .T.
      OLEDropMode = 0
      Caption = "TreeView Test"
      Name = "myTreeForm"
    
    
      ADD OBJECT TV1 AS myTreeView WITH ;
          Top = 0, ;
          Left = 0, ;
          Height = 252, ;
          Width = 180, ;
          Name = "TV1"
    
      ADD OBJECT text1 AS textbox WITH ;
          OLEDragMode = 1, ;
          Height = 23, ;
          Left = 204, ;
          Top = 36, ;
          Width = 156, ;
          Name = "Text1"
    
      ADD OBJECT commandcancel AS myCancel WITH ;
          Top = 156, ;
          Left = 216, ;
          Height = 27, ;
          Width = 84, ;
          Cancel = .T., ;
          Caption = "Cancel", ;
          Name = "commandCancel"
    ENDDEFINE
    
    DEFINE CLASS myTreeView as OleControl
      oleclass = 'MSComctlLib.TreeCtrl'
    
      PROCEDURE Init
    
        this.object.oledropmode = 1
    
        this.Nodes.Add( .null., 0, "A1", "Drop text here" )
    
      ENDPROC
    
      PROCEDURE OLEDragOver
        *** ActiveX Control Event ***
        LPARAMETERS oData, effect, button, shift, x, y, state
        LOCAL loNode
        IF oData.GetFormat(1) && 1=text
           loNode = THIS.HitTest( 15*x, 15*y )
           effect = 2
           THIS.DropHighlight = loNode
        ELSE
           effect = 0
        ENDIF
      ENDPROC
    
      PROCEDURE OLEDragDrop
        *** ActiveX Control Event ***
        LPARAMETERS oData, effect, button, shift, x, y
        LOCAL lcData, loNode
        IF oData.GetFormat(1) && text-format
           THIS.DropHighlight = .NULL.
           effect =2
           lcData = oData.GetData(1) && text-format
           loNode = THIS.HitTest( 15*x,15*y )
           MessageBox( 'Node at ('+TRANSFORM(x)+','+transform(y)+') Got data: ' + lcData )
           if VarType(loNode)='O'
              this.nodes.Add( loNode, 4, "A" + SYS(3), lcData )
              loNode.expanded = .t.
           else
              this.nodes.Add( .null., 0, "A" + SYS(3), lcData )
           endif
        ENDIF
      ENDPROC
    
    ENDDEFINE
    
    DEFINE CLASS myCancel as CommandButton
    
      PROCEDURE Click
        thisform.release()
      ENDPROC
    
    ENDDEFINE


    See also: Drag And Drop
    Has anyone ever noticed that in large treeview lists, occassionally a ToolTip is shown over certain nodes. This behaviour is reproducible (if anyone cares that is). In the ActiveX control, the tooltips property is not exposed (it is basically turned off.) . If anyone is interested in knowing how to turn them back on, post here and I will start off with some code that can be used to start a public project to retrieve the Tool Tips ( a Window of course) that were rightfully ours in the first place (:-)
    Peter Easson
    the Tooltip is shown when the node's text over which the mousepointer is located can't be completly shown in the treeview ...

    if someone want to supress this he/she might use the following code:
    #DEFINE TVS_NOTOOLTIPS 128
    #DEFINE GWL_STYLE -16
    DECLARE INTEGER SetWindowLong IN WIN32API INTEGER, INTEGER, INTEGER
    DECLARE INTEGER GetWindowLong IN WIN32API INTEGER, INTEGER
    
    LOCAL lnRet, lnHwnd
    lnHwnd = THISFORM.yourTreeView.hWnd
    lnRet = SetWindowLong(lnHwnd,GWL_STYLE, BITOR(TVS_NOTOOLTIPS,GetWindowLong(lnHwnd,GWL_STYLE)))


    CE
    Some tips on improving performance when adding and removing larger amounts of data to the Tree View:
    1. lock screen and moving the treeview off the screen before populating it
    2. get a direct reference to the "nodes" object
    3. set "scroll" property to .F. before adding nodes

    For example when adding to Tree:

    LOCAL theTree, theNodes
    theTree = thisform.olecontrol1
    theNodes = thisform.olecontrol1.Nodes
    
    thisform.LockScreen = .T.
    theTree.Top = 15000
    theTree.Left = 15000
    theTree.Scroll = .F.
    
    SCAN
      theNodes.Add(,1,pk_tree,myString)
    ENDSCAN
    
    theTree.Top = 10
    theTree.Left = 10
    theTree.Scroll = .T.
    thisform.LockScreen = .F.
    theTree = .Null.
    theNodes = .Null.



    For example to quickly clear the tree:

    LOCAL theTree, theNodes, lnNodeCount
    theTree = thisform.olecontrol1
    theNodes = thisform.olecontrol1.Nodes
    
    thisform.LockScreen = .T.
    
    theTree.Scroll = .F.
    theTree.Top = 10000
    theTree.Left = 10000
    
    lnNodecount = theNodes.Count
    FOR xj = nodeCount TO 1 STEP -1
      theNodes.Remove(xj)
    ENDFOR
    
    theTree.Top = 10
    theTree.Left = 10
    theTree.Scroll = .T.
    thisform.LockScreen = .F.
    
    theNodes = .null.
    theTree = .null.


    to mention is that when the "sorted" property is .T., adding to the tree is slightly quicker than when it's off, sounds unlogic doesn't it :)
    CE
    See Also: ClassTree
    Category ActiveXControls
    ( Topic last updated: 2011.03.25 12:59:12 PM )