Part 3: Automating PowerPoint 2010 and creating slides, shapes, connectors, and pictures by using data from the Visio 2010 shapes
Summary: The third article in a series of four articles about how to export Microsoft Visio 2010 shapes to Microsoft PowerPoint 2010. Part 3 discusses how to create new PowerPoint shapes by using data that is contained in ShapeConversion objects.
Last modified: June 12, 2012
Applies to: Office 2010 | PowerPoint 2010 | SharePoint Server 2010 | Visio 2010 | Visio Premium 2010 | Visual Studio 2010
Published: June 2012
Provided by: Eric Schmidt, Microsoft Corporation
The Exporting Visio 2010 Diagrams to PowerPoint 2010 add-in accomplishes its task by controlling the PowerPoint application from Visio. To do this, it captures a reference to a PowerPoint session by creating a new instance of PowerPoint.
Automating one application from another is only one way that you can accomplish this task. You can also create PowerPoint 2010 files using the Open XML SDK 2.0 for Microsoft Office. For more information about the , see About the Open XML SDK 2.0 for Microsoft Office.
As mentioned in Part 2: Writing the classes and methods that convert and export Visio 2010 diagrams to PowerPoint 2010, the OpenPPTSession method of the ThisAddIn class returns a new Presentation object to the calling code. Before it can create a new presentation, it must first create an instance of the Application class. Then, it uses the Add(MsoTriState) method to create a new Presentation object.
The AddPPTSlide method of the ThisAddIn class takes a Presentation object as an argument and returns a Slide object to the calling code by using the AddSlide(Int32, CustomLayout) method of the presentation passed in as an argument.
The AddSlide(Int32, CustomLayout) method has two required parameters:
Index, an integer that determines where the new slide is inserted in the Slides collection
pCustomLayout, which specifies the slide layout from the Slide Master to use for the new slide
The Exporting Visio 2010 Diagrams to PowerPoint 2010 add-in attempts to use the Blank slide layout of the default PowerPoint template for the exported Visio pages. The AddPPTSlide method first checks whether the seventh layout in the CustomLayouts collection (the Blank layout) exists and, if so, it captures a reference to that layout in the pptLayout variable. Otherwise, if the CustomLayouts collection does not include the seventh item, it instead returns the first item in the collection.
Below the definition of the ExportAllPages method of the ThisAddIn class in the ThisAddIn.vb or ThisAddIn.cs file, add the following code, which creates a new PowerPoint application object, creates a new presentation, and adds a slide to the presentation.
Public Function OpenPPTSession() As PowerPoint.Presentation ' Create a PowerPoint application object. Dim appPPT As PowerPoint.Application = New PowerPoint.Application ' Create a new PowerPoint presentation. Dim pptPreso As PowerPoint.Presentation = appPPT.Presentations.Add() Return pptPreso End Function Public Function AddPPTSlide(ByVal pptPreso As PowerPoint.Presentation) _ As PowerPoint.Slide ' Define pptLayout as the "Blank" layout of the default presentation template. ' If another template is set as default, select the first layout. Dim pptLayout As PowerPoint.CustomLayout If IsNothing(pptPreso.SlideMaster.CustomLayouts(7)) Then pptLayout = pptPreso.SlideMaster.CustomLayouts(1) Else pptLayout = pptPreso.SlideMaster.CustomLayouts(7) End If ' Create newSlide by using pptLayout. Dim newSlide As PowerPoint.Slide = pptPreso.Slides.AddSlide( _ (pptPreso.Slides.Count + 1), pptLayout) Return newSlide End Function
As mentioned earlier in Part 2: Writing the classes and methods that convert and export Visio 2010 diagrams to PowerPoint 2010, the Main method of the ThisAddIn class can convert a Visio shape to a PowerPoint shape in one of three ways: as a connector, as a picture, or as a built-in PowerPoint shape. The Main method uses the ShapeConversion.pptShapeType property to determine how it converts each shape. Depending on that value, the Main method calls either the ConstructPPTConnector method, the CopyPasteVisioToPPT method, or the ConstructPPTShape method of the ThisAddIn class.
The first method, ConstructPPTConnector, takes a ShapeConversion object as its parameter and constructs a new PowerPoint connector on the PowerPoint slide. It uses the AddConnector(MsoConnectorType, Single, Single, Single, Single) method to add a new shape to the Shapes collection of the pptBlankSlide object. The AddConnector(MsoConnectorType, Single, Single, Single, Single) method takes five parameters:
Type—A constant from the MsoConnectorType enumeration.
BeginX and BeginY—16-bit signed integers that specify the beginning point of the connector on the slide.
EndX and EndY—16-bit signed integers that specify the ending point of the connector on the slide.
The ConstructPPTConnector method creates a new elbow connector on the PowerPoint slide by using the ShapeConversion.pptConnectorBeginX, ShapeConversion.pptConnectorBeginY, ShapeConversion.pptConnectorEndX, and ShapeConversion.pptConnectorEndY properties to specify the endpoints of the PowerPoint connector. After adding the connector to the slide, the method sets the Name property to match the name of the original Visio connector, which is needed to connect shapes and connectors later.
In the ThisAddIn.vb or ThisAddIn.cs file, below the definition of the Main method, add the following code, which creates new elbow connector shapes on the PowerPoint slide (pptBlankSlide object).
Sub ConstructPPTConnector(ByVal currShapeConversion As ShapeConversion) ' Create the PowerPoint connector shape. Dim pptConnector As PowerPoint.Shape pptConnector = pptBlankSlide.Shapes.AddConnector( _ Microsoft.Office.Core.MsoConnectorType.msoConnectorElbow, _ currShapeConversion.pptConnectorBeginX, _ currShapeConversion.pptConnectorBeginY, _ currShapeConversion.pptConnectorEndX, _ currShapeConversion.pptConnectorEndY) ' Set the name of connector shape. pptConnector.Name = currShapeConversion.pptShapeName End Sub
The most difficult case that the Exporting Visio 2010 Diagrams to PowerPoint 2010 add-in must handle is when there is no PowerPoint analog to a Visio shape. In this circumstance, the add-in creates an Enhanced Metafile picture of the Visio shape on the PowerPoint slide. The CopyPasteVisioToPPT method takes a Visio.Shape object and a ShapeConversion object as arguments, and makes a copy of the Visio.Shape object on the PowerPoint slide.
When a Visio shape is copied and pasted as a picture into another program, the text is copied as part of the picture too. Unfortunately, this means that the text can no longer be edited or formatted. If a Visio shape to copy has text, the CopyPasteVisioToPPT method cuts the text and stores it in a hidden RichTextBox object so that the picture on the PowerPoint slide contains only the shape image without text. (Once the method pastes and formats the picture on the PowerPoint slide, it replaces the text in the Visio shape from the RichTextBox.)
The CopyPasteVisioToPPT method pastes the Visio shape onto the PowerPoint slide by using the PasteSpecial(PpPasteDataType, MsoTriState, String, Int32, String, MsoTriState) method, which returns a ShapeRange collection. The method then captures a reference to the first item in the ShapeRange collection—the picture itself—in a Shape object. Next, the method resizes, positions, and renames the picture, based on the values that are contained in the currShapeConversion object.
Also if the Visio shape contains text, the CopyPasteVisioToPPT method calls the AddTextOverlay method to add the text in a text box on top of the picture.
In the ThisAddIn.vb or ThisAddIn.cs file, below the definition for the ConstructPPTConnector method, add the following code, which copies a shape from Visio, pastes it onto the PowerPoint slide, and resizes the shape.
Sub CopyPasteVisioToPPT(ByVal shapeInt As Integer, _ ByVal currShapeConversion As ShapeConversion) Dim pptPic As PowerPoint.ShapeRange Dim pptShape As PowerPoint.Shape Dim rtfBox As RichTextBox = New RichTextBox Dim currVisioShape As Visio.Shape = visioPage.Shapes(shapeInt) Dim vsoCharacters As Visio.Characters = currVisioShape.Characters ' Remove text from the shape to exclude it from the picture. If Not String.IsNullOrEmpty(currShapeConversion.pptShapeText) Then vsoCharacters.Cut() rtfBox.Paste() currVisioShape.CellsU("Para.Bullet").FormulaU = 0 End If ' Paste the picture onto the PowerPoint slide ' and capture a reference to it. currVisioShape.Copy() pptPic = pptBlankSlide.Shapes.PasteSpecial( _ PowerPoint.PpPasteDataType.ppPasteEnhancedMetafile) pptShape = pptPic.Item(1) ' Adjust the dimensions of the shape and change the name. With pptShape .Name = currShapeConversion.pptShapeName .Width = currShapeConversion.pptShapeWidth .Left = currShapeConversion.pptShapeLeft .Top = currShapeConversion.pptShapeTop End With If currShapeConversion.pptShapeWidth = 0 Then pptShape.Height = currShapeConversion.pptShapeHeight End If ' Create a text box over the shape with the shape's text, if any. If Not String.IsNullOrEmpty(currShapeConversion.pptShapeText) Then AddTextOverlay(currShapeConversion) ' Cut and paste RTF from the text box back to the Visio shape. rtfBox.SelectAll() rtfBox.Cut() currVisioShape.Characters.Paste() End If End Sub
For the third conversion case, the ConstructPPTShape method creates a PowerPoint shape that is equivalent to the Visio shape and then formats the PowerPoint shape to match the Visio shape. The method uses the AddShape(MsoAutoShapeType, Single, Single, Single, Single) method to add a new Shape to the pptBlankSlide object. Because the ShapeConversion class constructor method converts the formatting values of the Visio shape to values that PowerPoint can interpret, the ConstructPPTShape method uses the exposed properties of the ShapeConversion object that is passed in as an argument to build and format the new Shape object.
After adding the Shape to the Shapes collection, the ConstructPPTShape method adds text to the shape, depending on whether the ShapeConversion.pptShapeText property contains a value. If the ShapeConversion.pptShapeText property is not null, the ConstructPPTShape method adds the text to the shape and then formats the text to match the Text 1 color value of the PowerPoint theme. Depending on the text added to the PowerPoint shape, the shape might increase or decrease in height or change position along the y-axis of the slide. To address this, the method resets the Shape object height and distance from the top edge of the slide if the shape is too small. (You can also set the AutoSize property of the TextFrame object that is associated with the Shape object to ppAutoSizeNone. However, this can result in the text becoming unreadable or compressed.
If you want to specify exact color values when you program PowerPoint 2010 using C#, you must first create a Color structure, and then use the ToArgb() method to convert the object to an integer value. The properties and methods in the PowerPoint 2010 primary interop assembly that set and get specific colors accept only integer values that express RGB values.
Also note that you must add the using System.Drawing directive to your code to have access to the Color structure.
Under the CopyPasteVisioToPPT method in the ThisAddIn.vb or ThisAddIn.cs file, add the following code, which uses a ShapeConversion object to create a new PowerPoint shape on the PowerPoint slide.
Sub ConstructPPTShape(ByVal currShape As ShapeConversion) ' Create a PowerPoint shape on pptBlankSlide. Dim pptShape As PowerPoint.Shape = _ pptBlankSlide.Shapes.AddShape(currShape.pptShapeType, _ currShape.pptShapeLeft, _ currShape.pptShapeTop, _ currShape.pptShapeWidth, _ currShape.pptShapeHeight) ' Rename and apply fill color to the new PowerPoint shape. With pptShape .Name = currShape.pptShapeName .Fill.Solid() .Fill.ForeColor.RGB = currShape.pptShapeFillColor End With ' Add shape text, if any. If Not String.IsNullOrEmpty(currShape.pptShapeText) Then With pptShape .TextFrame.TextRange.Text = currShape.pptShapeText .TextFrame.TextRange.Font.Color.ObjectThemeColor = _ MsoThemeColorIndex.msoThemeColorText1 End With ' Check the resizing of the PowerPoint shape with autosizing. If pptShape.Height < currShape.pptShapeHeight Then ' Resize the shape if it is too small. pptShape.Height = currShape.pptShapeHeight pptShape.TextFrame.AutoSize = PowerPoint.PpAutoSize.ppAutoSizeNone pptShape.Top = currShape.pptShapeTop End If End If End Sub
As mentioned earlier, pictures (and connectors) in PowerPoint do not contain TextFrame objects that you can use to display text on the slide. The Exporting Visio 2010 Diagrams to PowerPoint 2010 add-in addresses this issue by overlaying pictures with a text box that contains the text from the Visio shape. Specifically, the AddTextOverlay method of the ThisAddIn class uses the AddTextbox(MsoTextOrientation, Single, Single, Single, Single) method to create a new text box that uses the left, top, width, and height values of the original shape. (The complete version of the Exporting Visio 2010 Diagrams to PowerPoint 2010 add-in uses the spatial values of the text block of the original Visio shape.) After the text box shape is created, the method adds the text that is contained in the ShapeConversion.pptShapeText property to the text box and formats the text.
Under the ConstructPPTShape method in the ThisAddIn.vb or ThisAddIn.cs file, add the following code, which creates a text box shape over the picture shapes that the CopyPasteVisioToPPT method creates.
Sub AddTextOverlay(ByVal currShapeConversion As ShapeConversion) ' Create a text box (with text) on top of, and centered on the shape. Dim pptShpText As PowerPoint.Shape = pptBlankSlide.Shapes.AddTextbox( _ Office.MsoTextOrientation.msoTextOrientationHorizontal, currShapeConversion.pptShapeLeft, _ currShapeConversion.pptShapeTop, _ currShapeConversion.pptShapeWidth, _ currShapeConversion.pptShapeHeight) ' Add and format the text in the text box. With pptShpText .TextFrame.AutoSize = PowerPoint.PpAutoSize.ppAutoSizeNone .TextFrame.TextRange.Text = currShapeConversion.pptShapeText .TextFrame.TextRange.Font.Color.ObjectThemeColor = _ MsoThemeColorIndex.msoThemeColorText1 End With ' Change the background of the text box to match the slide background ' if the shape is a connector. If currShapeConversion.pptShapeType = 0 Then pptShpText.TextFrame.TextRange.ParagraphFormat.Alignment = _ Microsoft.Office.Core.MsoParagraphAlignment.msoAlignCenter pptShpText.Fill.ForeColor.ObjectThemeColor = _ MsoThemeColorIndex.msoThemeColorBackground1 End If ' Reposition the text box after adding the text. With pptShpText .Left = currShapeConversion.pptShapeLeft .Top = currShapeConversion.pptShapeHeight End With End Sub
The ConnectShapes method, which is called during the second loop of the Main method of the ThisAddIn class, connects a PowerPoint connector and PowerPoint shape on the slide. The method has a single parameter named visConnect, a Visio.Connect object, which defines a connection between a Visio shape and a Visio connector. If the Visio shape that is returned by the Connect.FromSheet property is a dynamic connector, the method gets a reference to the corresponding PowerPoint shape and connector on the slide. The method then uses the Connect.FromPart property of the Visio.Connect object to determine which end of the connector is connected to the shape. Depending on the end that is connected, the ConnectShapes method calls the BeginConnect(Shape, Int32) or the EndConnect(Shape, Int32) method of the Shape object to attach the connector to the shape.
The method also calls the RerouteConnections() after both ends of the connector are connected. If either end of the connector is not connected, any call made to the RerouteConnections() method raises an exception. Most often, the Connect objects in the Connects collection are arranged so that the first Connect object that references a dynamic connector is the beginning connection, and the next object in the collection is the ending connection. Thus, the ConnectShapes method calls the RerouteConnections() method after the EndConnect(Shape, Int32) method is called.
Below the AddTextOverlay method of the ThisAddIn class in the ThisAddIn.vb or ThisAddIn.cs file, add the following code, which takes a Connect object as an argument and connects two PowerPoint shapes on the PowerPoint slide.
Sub ConnectShapes(ByRef visConnect As Visio.Connect) ' Get the names of the two connected shapes. Dim cnctrName As String = visConnect.FromSheet.Name Dim shapeName As String = visConnect.ToSheet.Name ' Check that connector shape is a Dynamic connector. If (cnctrName.ToLower.Contains("connector")) Then ' Get analog shapes on the PowerPoint slide. Dim pptConnector As PowerPoint.Shape = pptBlankSlide.Shapes(cnctrName) Dim pptShape As PowerPoint.Shape = pptBlankSlide.Shapes(shapeName) ' Get the relationship of the connection point ' to the connector and shape. Dim cnctEnd As Integer = visConnect.FromPart ' If the pptConnector begins at the connection point with the ' pptShape, use the BeginConnect method. If (cnctEnd = 9) Then pptConnector.ConnectorFormat.BeginConnect(pptShape, 1) ' Otherwise, connect the end of the pptConnector to the pptShape. Else pptConnector.ConnectorFormat.EndConnect(pptShape, 1) ' Reroute the pptConnector to the closest connection point ' on the pptShape. pptConnector.RerouteConnections() End If End If End Sub