TextFrames.vb
''
'' This code is part of GrapeCity Documents for Word samples.
'' Copyright (c) GrapeCity, Inc. All rights reserved.
''
Imports System.IO
Imports System.Drawing
Imports System.Collections.Generic
Imports System.Linq
Imports GrapeCity.Documents.Word

'' This sample demonstrates how to add linked text frames to a DOCX,
'' with text spanning the frames.
Public Class TextFrames
    Public Function CreateDocx() As GcWordDocument
        Dim doc = New GcWordDocument()

        doc.Load(Path.Combine("Resources", "WordDocs", "SampleParagraphs.docx"))

        '' Locate the paragraphs for inserting text frames:
        Const p1start = "This is the first paragraph of the original document"
        Const p2start = "This is the second paragraph of the original document"
        Const p3start = "This is the third paragraph of the original document"
        Const p4start = "This is the fourth paragraph of the original document"

        '' Find individual paragraphs inside the document:
        Dim p1 = Nothing, p2 = Nothing, p3 = Nothing, p4 = Nothing
        For Each p In doc.Body.Paragraphs
            Dim t = p.GetRange().Text
            If (t.StartsWith(p1start)) Then
                p1 = p
            ElseIf (t.StartsWith(p2start)) Then
                p2 = p
            ElseIf (t.StartsWith(p3start)) Then
                p3 = p
            ElseIf (t.StartsWith(p4start)) Then
                p4 = p
            End If
        Next
        If p1 Is Nothing OrElse p2 Is Nothing OrElse p3 Is Nothing OrElse p4 Is Nothing Then
            Throw New Exception("Unexpected: could not find paragraphs.")
        End If

        '' Add new style for text in frames:
        Dim style = doc.Styles.Add("FrameTextStyle", StyleType.Character)
        style.Font.Color.RGB = Color.DarkBlue
        style.Font.Bold = True

        '' Generate a long text that we will put into linked text frames:
        Dim ts = ""
        For i = 0 To 11
            ts += $"Text frame content {i}. "
        Next

        '' NOTE: shapes (including text frames) can be added to text runs only
        '' (e.g. we cannot add a shape directly to a paragraph).

        '' Add a text run at the end of the first paragraph:
        Dim r1 = p1.GetRange().Runs.Add(" Text run added to paragraph 1. The first shape is inserted inline after this. ")

        '' Add a shape to the new text run:
        Dim s1 = r1.GetRange().Shapes.Add(96, 72)

        '' Add a text frame with the generated text to the new shape:
        Dim tf1 = s1.AddTextFrame(CType(ts, String))
        tf1.Format.Margin.AllEdges = 4

        For Each r In tf1.GetRange().Runs
            If r1 IsNot r Then
                r.Style = style
            End If
        Next

        '' The text in the frame is rather long, and will not fit inside s1.
        '' Text frames can be linked so that a long text can span several frames.
        '' We add two linked frames, one to 2nd paragraph, and one to the first
        '' paragraph on the page:
        Dim r2 = p2.GetRange().Runs.Add(" Text run added to paragraph 2. The second shape is inserted inline after this. ")
        Dim shapes = r2.GetRange().Shapes

        Dim s2 = r2.GetRange().Shapes.Add(192, 72)
        Dim ltf2 = s2.AddLinkedTextFrame(tf1)

        '' Default wrap format type for new shapes is inline.
        '' Here we change the 3rd shape's wrap to square with absolute position
        '' relative to the very first paragraph in the document:
        Dim s3 = doc.Body.Paragraphs.First.GetRange().Runs.First.GetRange().Shapes.Add(144, 96)
        Dim ltf3 = s3.AddLinkedTextFrame(tf1)

        s3.WrapFormat.Type = WrapType.Square
        s3.Position.Vertical.Type = ShapePositionType.Points
        s3.Position.Vertical.Offset = 0
        s3.Position.Horizontal.Type = ShapePositionType.Points
        s3.Position.Horizontal.Offset = doc.Body.Sections.First.PageSetup.ClientWidth - 144

        Return doc
    End Function
End Class