Link to home
Start Free TrialLog in
Avatar of rondeauj
rondeauj

asked on

Treeview

Does anyone have a good method of printing the treeview?  I want to print Icons, Labels, +/- and lines.  No HTML, but I will use three party controls.  More points for GOOD source code.

Thanks in advance,
Avatar of rondeauj
rondeauj

ASKER

Adjusted points to 185
r u going to print as hardcopy or just display in the HTML format ?

I have done this with Word and OLE2, it was an hard job, but a very beatiful report.
Here is a small function do print a Treeview node by node.
This version print only text to the immediat window with debug string, but you could easily use the printer with Print and PaintPicture method instead.

Option Explicit

Private Const MAX_INDENT = 10
Private bBoudin(0 To MAX_INDENT) As Boolean

Public Sub PrintTreeView(ByRef tv As TreeView, prt As Object)

    Dim i As Integer
    Dim n As Node
   
    Set n = tv.Nodes(1)
    Do
        PrintTreeviewNode tv, n, 0, prt
       
        Set n = n.Next
    Loop While Not (n Is Nothing)
   
End Sub

Public Sub PrintTreeviewNode(ByRef tv As TreeView, ByRef nd As Node, ByVal lvl As Integer, ByRef prt As Object)
    Dim i As Integer
    Dim s As String
    Dim n As Node
   
    s = ""
   
    'Print boudins
    For i = IIf(tv.LineStyle = tvwRootLines, 0, 1) To lvl - 1
        If bBoudin(i) Then
            s = s & " | "
        Else
            s = s & "   "
        End If
    Next
   
    bBoudin(lvl) = Not (nd.Next Is Nothing)
   
    If tv.LineStyle = tvwRootLines Or lvl > 0 Then
        If nd.Children Then
            If nd.Next Is Nothing Then
                s = s & " ""-"
            Else
                s = s & " +-"
            End If
        Else
            If nd.Next Is Nothing Then
                s = s & " '-"
            Else
                s = s & " |-"
            End If
        End If
    End If
   
    s = s & nd.Text
   
    Debug.Print s
   
    If nd.Children Then
        Set n = nd.Child
        Do
            PrintTreeviewNode tv, n, lvl + 1, prt
       
            Set n = n.Next
        Loop Until n Is Nothing
    End If
   
End Sub

Private Sub Command1_Click()
    PrintTreeView TreeView1, Picture1
End Sub

Private Sub Form_Load()

    Dim n As Node, m As Node
   
    TreeView1.Nodes.Add Text:="Item 1"
    TreeView1.Nodes.Add Text:="Item 2"
    TreeView1.Nodes.Add Text:="Item 3"
    Set n = TreeView1.Nodes.Add(Text:="Item 4")
    TreeView1.Nodes.Add n, tvwChild, , "Item 5"
    TreeView1.Nodes.Add n, tvwChild, , "Item 6"
    TreeView1.Nodes.Add n, tvwChild, , "Item 7"
    TreeView1.Nodes.Add n, tvwChild, , "Item 8"
    TreeView1.Nodes.Add n, tvwChild, , "Item 9"
    TreeView1.Nodes.Add n, tvwChild, , "Item 10"
    TreeView1.Nodes.Add n, tvwChild, , "Item 11"
    TreeView1.Nodes.Add n, tvwChild, , "Item 12"
    TreeView1.Nodes.Add n, tvwChild, , "Item 13"
    TreeView1.Nodes.Add n, tvwChild, , "Item 14"
    TreeView1.Nodes.Add n, tvwChild, , "Item 15"
    Set n = TreeView1.Nodes.Add(Text:="Item 16")
    TreeView1.Nodes.Add n, tvwChild, , "Item 17"
    TreeView1.Nodes.Add n, tvwChild, , "Item 18"
    TreeView1.Nodes.Add n, tvwChild, , "Item 19"
    TreeView1.Nodes.Add n, tvwChild, , "Item 20"
    TreeView1.Nodes.Add n, tvwChild, , "Item 21"
    TreeView1.Nodes.Add n, tvwChild, , "Item 22"
    TreeView1.Nodes.Add n, tvwChild, , "Item 23"
    TreeView1.Nodes.Add Text:="Item 24"
    TreeView1.Nodes.Add Text:="Item 25"
    TreeView1.Nodes.Add Text:="Item 26"
    TreeView1.Nodes.Add Text:="Item 27"
    TreeView1.Nodes.Add Text:="Item 28"
    TreeView1.Nodes.Add Text:="Item 29"
    Set n = TreeView1.Nodes.Add(Text:="Item 30")
    Set n = TreeView1.Nodes.Add(n, tvwChild, , "Item 31")
    Set m = TreeView1.Nodes.Add(n, tvwChild, , "Item 32")
    Set n = TreeView1.Nodes.Add(m, tvwChild, , "Item 33")
    TreeView1.Nodes.Add m, tvwNext, , "Item 34"
End Sub

I do not want to print it with HTML, but I will look at examples. I do want to capture the line and icons if possible.
Do you want to print the tree as it appears on the screen?  Or fully expanded as a diagram.  If you want to print it as it appears on the screen you could do a window capture on the treeview control (same type of code used for capturing the desktop window as a graphic).  Then you could print it any way that you would print a picture control.  But, this is only going to print what is actually displayed in the window.

MD
No I want to print the tree fully expanded.

mdougan<< Thanks for the input, that will help me with another problem that was just presented to me.  Still need to print the treeview.
Here is a new version that print treeview to a picturebox or to printer, graphicly with treelines and icons.

Put this code into a module

Option Explicit

Public Const INDENT_WIDTH = 300
Public Const ITEM_HEIGTH = 200

Private Const MAX_INDENT = 10
Private bBoudin(0 To MAX_INDENT) As Boolean

Public Sub PrintTreeview(ByRef tv As TreeView, prt As Object)

    Dim i As Integer
    Dim n As Node
   
    Debug.Assert (TypeOf prt Is PictureBox) Or (TypeOf prt Is Printer)
   
    Set n = tv.Nodes(1)
    Do
        PrintTreeviewNode tv, n, 0, prt
       
        Set n = n.Next
    Loop While Not (n Is Nothing)
   
End Sub

Private Sub PrintTreeviewNode(ByRef tv As TreeView, ByRef nd As Node, ByVal lvl As Integer, ByRef prt As Object)
    Dim i As Integer
    Dim n As Node
    Dim x0 As Single, y0 As Single
   
    x0 = 0
    y0 = prt.CurrentY
   
    'Print boudins
    For i = IIf(tv.LineStyle = tvwRootLines, 0, 1) To lvl - 1
        If bBoudin(i) Then
            prt.Line (x0 + INDENT_WIDTH \ 4, y0)-Step(0, ITEM_HEIGTH), vbBlack
        End If
        x0 = x0 + INDENT_WIDTH
    Next
   
    bBoudin(lvl) = Not (nd.Next Is Nothing)
   
    If tv.LineStyle = tvwRootLines Or lvl > 0 Then
        If nd.Next Is Nothing Then
            prt.Line (x0 + INDENT_WIDTH \ 4, y0)-Step(0, ITEM_HEIGTH \ 2), vbBlack
            prt.Line -Step(INDENT_WIDTH - INDENT_WIDTH \ 4, 0), vbBlack
        Else
            prt.Line (x0 + INDENT_WIDTH \ 4, y0)-Step(0, ITEM_HEIGTH), vbBlack
            prt.CurrentY = prt.CurrentY - ITEM_HEIGTH \ 2
            prt.Line -Step(INDENT_WIDTH - INDENT_WIDTH \ 4, 0), vbBlack
        End If
        x0 = x0 + INDENT_WIDTH
    End If
   
    If Not (tv.ImageList Is Nothing) _
        And (tv.Style And (tvwPictureText Or tvwPlusPictureText Or tvwTreelinesPictureText Or tvwTreelinesPlusMinusPictureText)) Then
        If Len(nd.Image) Then
            prt.PaintPicture tv.ImageList.ListImages.Item(nd.Image).Picture, x0, y0
        End If
        x0 = x0 + INDENT_WIDTH
    End If
   
    prt.CurrentX = x0
    prt.CurrentY = y0
    prt.Print nd.Text
   
    prt.CurrentY = y0 + ITEM_HEIGTH
   
    If nd.Children Then
        Set n = nd.Child
        Do
            PrintTreeviewNode tv, n, lvl + 1, prt
       
            Set n = n.Next
        Loop Until n Is Nothing
    End If
   
End Sub

The source code you provided works great, but it has one fault. If you printing of the treeview goes beyond 1 page it goes nuts and prints each following node on a different page. I had to adjust the spacing of the height because icons were covering each other. Could this be causing the problem? I will gladly award you the points if you can tune this out.  Thanks in advance.
ASKER CERTIFIED SOLUTION
Avatar of chabaud
chabaud

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I made the following changes to your code:

Public Const INDENT_WIDTH = 300
Public Const ITEM_HEIGTH = 300



 Set n = tv.Nodes(1)
    Do
        PrintTreeviewNode tv, n, 0, prt
            If Printer.CurrentY >= Printer.Height - 1000 Then Printer.NewPage
        Set n = n.Next
    Loop While Not (n Is Nothing)
     


If nd.Children Then
        Set n = nd.Child
        Do
            PrintTreeviewNode tv, n, lvl + 1, prt
                If Printer.CurrentY >= Printer.Height - 1000 Then Printer.NewPage
            Set n = n.Next
        Loop Until n Is Nothing
End If


   Now it works great!  I looked all over the net for sample code and third party controls that would do just this.  Great Job. You need to create a control for this.

   I would give you more than 195 But that is all I have.