ComponentOne VSView 8.0
Build a Table of Contents

This example shows how you can build a Tableof Contents for a VSPrinter document. The example is based on the use of document tags. The sample also takes advantage of the tags to implement hyperlinks, so if you right-click on an entry in the Table of Contents, the VSPrinter control will jump to the topic in the main document.

To create the TOC example, start by adding the following controls to a new VB form:

Add the following code to the btnDoIt_Click event handler:

Example Title
Copy Code
Private Sub btnDoIt_Click()

With vp

 

  ' set up document

  .Orientation = orPortrait

  .PageBorder = pbBottom

  .Footer = "VSPrint8|TOC Sample|%d"

 

  ' define styles

  .SpaceAfter = "8pt"

  .IndentLeft = "0.75in"

  .Styles.Add "Normal", vpsAll

 

  .SpaceBefore = "20pt"

  .IndentLeft = 0

  .FontBold = True

  .FontSize = 2 * .FontSize

  .Styles.Add "Heading", vpsAll

  .Styles.Apply "Normal"

  .SpaceAfter = 0

  .IndentLeft = 0

  .FontBold = True

  .TextColor = RGB(0, 0, 150)

  .TableBorder = tbNone

  .Styles.Add "TOC", vpsAll

  ' create document with 50 headers

  .StartDoc

  Dim i%, pg%, pgTOC%, s$

  For i = 1 To 50

 

    ' create ith header with header tag

    s = GetRandomTitle()

    .Styles.Apply "Heading"

    .StartTag "H1|" & i & "|" & s

    .Paragraph = i & " " & s

    .EndTag

 

    ' create some text

    s = GetRandomText()

    .Styles.Apply "Normal"

    .Paragraph = s

  Next

  ' create TOC

  .NewPage

  pgTOC = .PageCount

  .Styles.Apply "Heading"

  .Paragraph = "Random Document" & vbCrLf & "Table of Contents"

  .Styles.Apply "Normal"

  .IndentLeft = 0

  .Paragraph = "This is a live table of contents. " & _

               "Right-click on any item to jump to it."

  .Footer = ""

 

  ' look for tags, add an entry for each one

  vp.Styles.Apply "TOC"

  For i = 1 To 20000

 

    ' look for ith tag, quit if not found

    pg = vp.FindTag("H1|" & i & "|")

    If pg <= 0 Then Exit For

 

    ' retrieve full tag text and add TOC entry

    s = vp.RetrieveTag(vp.X1, vp.Y1, vp.X2, vp.Y2, pg)

    AddToTOC vp, s, pg

  Next

  vp.Styles.Apply "Normal"

   

  ' done

  .EndDoc

 

  ' move TOC to front

  .MovePages pgTOC, .PageCount, True

 

End With

End Sub

This routine starts by creating a long document consisting of 50 random headings with bodies of random text. Each heading has a "heading tag" associates with it. The tags are created with the StartTag and EndTag methods, and have the format "H1|n|s", where H1 indicates this is a level 1 heading, n is the heading's sequential number, and s is the heading text.

When the document is done, the routine starts a new page with the Table of Contents. Then it builds the table of contents by searching the document for the heading tags ("H1|1", "H1|2", and so on) using the FindTag property. For each tag found, the code uses the RetrieveTag property to retrieve the full tag text, and then calls the AddToTOC routine to write out the TOC entry.

Finally, the MovePages method is used to move the TOC to the beginning of the document.

The AddToTOC routine follows:

Example Title
Copy Code
Sub AddToTOC(vp As VSPrinter, s As String, pg As Integer)

  Dim sDots$, v

 

  ' create a line of dots to include in the entry

  sDots = " . . . . . . . . ."

  sDots = sDots & sDots & sDots & sDots

   

  ' create TOC tag

  vp.StartTag "TOC|" & pg & "|" & vp.Y1 & "|" & vp.Y2

   

  ' create TOC entry ("~" prevents col 2 from wrapping dots)

  v = Split(s, "|")

  vp.AddTable ">800|~6000|>500", "", _

                v(1) & ":|" & v(2) & sDots & "|" & pg

   

  ' finish TOC tag and be done

  vp.EndTag

   

End Sub

The AddToTOC routine builds a TOC tag formatted as "TOC|pg|y1|y2", where pg is the page where the entry can be found in the document body, and y1 and Y2 are the vertical coordinates of the entry. This information will be used to provide hyperlinks into the document body. Then is uses the AddTable method to write out the actual TOC entry.

To take advantage of the TOC tags and make the hyperlinks work, add the following vp_MouseDown event handler:

Example Title
Copy Code
Private Sub vp_MouseDown(Button As Integer, Shift As Integer, _

                         X As Single, Y As Single)

  Dim s$, v

 

  ' make sure we're using the right button

  If Button <> 2 Then Exit Sub

   

  ' get TOC tag

  s = vp.RetrieveTag(X, Y, , , , True)

  If Left(s, 4) <> "TOC|" Then Exit Sub

           

  ' jump to saved position

  v = Split(s, "|")

  vp.PreviewPage = v(1) + vp.FindTag("H1|1") - 1

  vp.ScrollIntoView 0, v(2), 300, v(3)

 

End Sub

The routine starts by checking which mouse button was pressed. Then it tries to retrieve a TOC tag from the current mouse position (using the RetrieveTag property).

If a TOC tag is found, the code calculates the page number by extracting the original page number from the tag (v(1)) and applying an offset to account for the fact that the page number changed when we moved the tag to the front of the document using the MovePages method.

Finally, the jump is executed using the PreviewPage property and ScrollIntoView method. This makes the selected heading visible to the user.

The only thing missing is the code that generates random text. Here it is:

Example Title
Copy Code
Function GetRandomTitle() As String

  Dim s$, v

  v = Split("Learning|Explaining|Examining|Applying|Using|Destroying", "|")

  s = s & v(Rnd() * UBound(v)) & " "

  v = Split("Modern Art|Fast Food|Gardening|Investments", "|")

  s = s & v(Rnd() * UBound(v)) & " "

  v = Split("Quickly|Painlessly|Slowly|Painfully|With Panache", "|")

  s = s & v(Rnd() * UBound(v))

  GetRandomTitle = s

End Function

Function GetRandomText() As String

  Dim s$, i%

  For i = 0 To 10 + Rnd * 50

    s = s & GetRandomSentence()

    If Rnd < 0.3 Then s = s & vbCrLf

  Next

  GetRandomText = s

End Function

Function GetRandomSentence() As String

  Dim s$, v

  v = Split("Artists|Modern thinkers|Gardeners|Experts|Some people", "|")

  s = s & v(Rnd() * UBound(v)) & " "

  v = Split("know|seem to ponder|would care about|often discuss|dream about", "|")

  s = s & v(Rnd() * UBound(v)) & " "

  v = Split("the movies|chicken soup|tea|many things|sushi|my car", "|")

  s = s & v(Rnd() * UBound(v)) & " "

  v = Split("incessantly|too much|easily|without reason|rapidly|sadly", "|")

  s = s & v(Rnd() * UBound(v))

  GetRandomSentence = s & ". "

End Function

That's it. If you run the program now, you will get output that looks like the following image. Try tracing through the code to see exactly how the tags work.

 

 


Copyright (c) GrapeCity, inc. All rights reserved.

Product Support Forum  |  Documentation Feedback