This document details the common pitfalls when developing for PowerPointLabs, so that these mistakes can be noted/avoided by future contributors.
-
The index of an Office collection starts from 1, however note that the index of a collection provided by .NET starts from 0
ShapeRange range = getCurrentSelectedShapes(); range[1] ... ; //the first element
-
When you delete, cut, or ungroup a shape programmatically, and you undo this change from the PowerPoint UI, then that shape will become corrupted. For a corrupted shape, accessing attributes programatically other than it's
left
/top
/width
/height
/name
would throw an exception.
One possible solution would be re-allocate the shape’s memory; copy and paste it programmatically before you handle the shape.
Another possible solution would be to use the method calledCorruptionCorrection
, located inShapeUtil
, for fixing corrupted shapes although it may not work for every type of corruption -
When dealing with pictures or shapes, your features should not override user's clipboard contents. Use the
RestoreClipboardAfterAction
method inClipboardUtil
if your feature requires copying/pasting to maintain user's clipboard contents -
When pasting a shape programmatically, it is not selected in Office 2010, but selected in Office 2013
-
When using
shape.Duplicate()
, the animations are copied in Office 2013 but not 2016. Recommended to useslide.RemoveAnimationsForShape()
to remove animations -
When pasting a shape in the current slide, its naming mechanism is like this:
- Index increment for default name. E.g. Rectangle 1 -> Rectangle 2
- Unchanged for non-default name. E.g. MyRectangle -> MyRectangle
-
Some Office APIs are not supported for Office 2010, e.g.
MergeShape
. When developing, special attention needs to be given to APIs available for Office 2010 -
Some Office APIs may not work correctly, e.g.
WindowBeforeDoubleClick
event. You may have to use a workaround. Be sure to include a short comment in the code if a non-conventional workaround is used -
When a shape is rotated, its position attributes, i.e.
left
andtop
, will always return the value when its rotation angle is at zero. Thus to get the rotated position, you may calculate it using its rotation matrix -
When you need to convert Shape(s) to a ShapeRange object, you can consider using the
ToShapeRange
method inPowerPointSlide
-
Effects rendering is slow, especially for pictures and 3D images. You may try to avoid it, or make it rendered (e.g. export the picture with effects, and then insert it again)
-
When you copy and paste a slide, the slide name will be lost:
- Original slide name = “My slide”
- After paste slide name = “Slide\d+”
-
Event triggering order of
WindowDeactivated
andPresentationClose
is different between PowerPoint 2010 and 2013. In 2010,PresentationClose
will be triggered beforeWindowDeactivated
, but this order is reversed in 2013 -
Accessing the
ActivePresentation.Saved
property on a new, unsaved presentation, always results in theActivePresentation.Saved
property returningmsoFalse
, regardless of whether the new presentation contains any valid changes to be saved. -
Visual Studio may show the error "Output Type of Class Library cannot be started directly", shown below. This is caused by errors in Visual Studio's project configuration.
The default fix is to delete the .vs folder in ./PowerPointLabs/PowerPointLabs for Visual Studio to recreate the configuration files. Alternatively, you can do the following:
Step 1. Right click Solution 'PowerPointLabs' (3 projects) in the solution explorer.
Step 2. Click Properties.
Step 3. Navigate to Common Properties > Startup Project.
Step 4. Select Single startup project and choose PowerPointLabs from the drop down list.
-
When grouping multiple
Shape
objects together, it is not straightforward to do so with only references to theShape
objects. An easy way is to extract aShapeRange
object from the slide based on the names of theShapes
, and then calling theGroup()
method on thatShapeRange
.
string[] names = new string[] { shape1.Name, shape2.Name };
Shape group = this.GetCurrentSlide().Shapes.Range(names).Group();