I do a lot of presentations, and often you need to show the code "in parts", that is, to show the train of thought in the process of sequential writing of code. Unfortunately, PowerPoint is not configured for such purposes. So I decided to write an extension for PowerPoint 2007 that would auto-generate a sequence of slides with a “progressive scan” of code and comments. Actually this will be the story.
Idea
First try to explain the idea. Do you have a piece of code, let's say this [
1 ]:
public static T DeepCopy<T>( this IPrototype<T> obj)<br/>
{<br/>
T copy;<br/>
using (MemoryStream stream = new MemoryStream())<br/>
{<br/>
BinaryFormatter formatter = new BinaryFormatter();<br/>
formatter.Serialize(stream, obj);<br/>
stream.Seek(0, SeekOrigin.Begin);<br/>
copy = (T)formatter.Deserialize(stream);<br/>
stream.Close();<br/>
}<br/>
return copy;<br/>
}<br/>
This code I want to explain in parts on the slides. For example, initially you can show this:
//
public static T DeepCopy<T>( this IPrototype<T> obj)<br/>
{<br/>
And then, here it is:
//
public static T DeepCopy<T>( this IPrototype<T> obj)<br/>
{<br/>
//
T copy;<br/>
And so on. It would seem - you can use the built-in animation [
2 ], but it is inflexible - because even if you hide, for example, a piece of code, the place for it will still be allocated, which is not good. And what if you need to hide not a paragraph or a line, but only a couple of letters (for example, a keyword)? That's just for this purpose I decided to write my second [
3 ] add-in for PowerPoint.
Interface
Add-ons for Office are very easy to write: to do this, use the VSTO (Visual Studio Tools for Office) add-ons. In the studio, the corresponding types of projects appear, from which I have chosen the PowerPoint 2007 Add-In:

What is very good is the fact that our generated project is ready for use. It works
on F5 debugging , and what's nice is that even if I'm not in the studio, the add-in
remains in PowerPoint , which allows me to “eat my dog ​​food” in my free time. [
4 ]
Since the office uses tape controls (ribbons), the studio supports work with these controls. To create ribbon elements there is even a special designer:

I only needed one button for the interface, which significantly simplified the task (upd: now there are already 3 of them):

Modal interface
The studio has a problem (I don’t know, maybe it was decided in 2010) that WPF windows cannot be added to the extensions project, be it studio or office extensions. Usually I solve this problem with a separate assembly, but in this case I wanted to try to pee on WinForms, and for the interface I chose free (and quite beautiful) Krypton controls. Here is how this case looks in the completed version:

Not bad, is it? All this for free, and is available
here . But how the add-in window opens is worth explaining. Remember our ribbon? So - in the add-in class itself, it is not registered anywhere! Ribbon is created automatically! And then everything is simple - an event is tied to our button, which actually makes the predictable call
ShowDialog()
.
Working with slides
Since the internal logic of the add-in is rather boring, I’ll tell you how to programmatically create slides in a presentation. First of all, you need somewhere to keep a link to PowerPoint itself. To do this, I simply created a static variable and cached the value I received during the initialization of the add-in:
public static Application App;<br/>
<br/>
private void OnStartup( object sender, EventArgs e)<br/>
{<br/>
App = Application;<br/>
if (ApplicationStartedEvent != null )<br/>
ApplicationStartedEvent( this , null );<br/>
}<br/>
Now our button handler (well, the one in the ribbon) can get the same link, and from it the “active” presentation of the user (that is, the one the user works with):
var app = ThisAddIn.App;<br/>
var p = app.ActivePresentation;<br/>
Add a new slide to the presentation - easy. Remember the layout types you can choose for a slide? So, here they are enums, so everything is very simple:
')
Slide s = p.Slides.Add(<br/>
1+p.Slides.Count, //
PpSlideLayout.ppLayoutText //
);<br/>
Further - even easier. The slide with our
ppLayoutText
layout has a title and a main text field. These objects are available in the
Shapes
collection of the slide (do not forget that collections are indexed from one, not from scratch). Here's an example of how you can set the title text:
var title = s.Shapes[1];<br/>
title.TextFrame2.TextRange.Text = cff.ApplicationSettings.SlideTitle;<br/>
By the way, I note that using the
var
keyword helps a lot when developing. What else is noticeable is that when writing the whole add-in I never had to use the value of
missing
, which is one of the main inconveniences when working with an office extension. In C # 4, such a problem is of course no more.
Here is an example of how to manipulate the properties of the text box. In my case, I set the user-defined font and also remove the default fields and “bullets”:
var code = s.Shapes[2].TextFrame2.TextRange;<br/>
code.ParagraphFormat.FirstLineIndent = 0;<br/>
code.ParagraphFormat.Bullet.Visible = MsoTriState.msoFalse;<br/>
code.Font.CopyFrom(cff.ApplicationSettings.CodeFont);<br/>
code.ParagraphFormat.RightIndent = 0;<br/>
code.ParagraphFormat.LeftIndent = 0;<br/>
code.ParagraphFormat.SpaceBefore = 0;<br/>
Note that the extension method is used for fonts. The problem is that Office uses its
Font2
type, and the conversion from
System.Drawing.Font
course not defined. Also note that in the office, the types
true
and
false
are enums so that you can set the values ​​“yes”, “no”, and “not set”. Again, it is not difficult if you want to determine the conversion from our
bool
to the office
MsoTriState
.
Work with text
As you may have guessed, the text is put into an object of type
TextFrame2
. When you add text to a frame, you get a link to the section of code that you added:
var range = textarea.TextFrame2.TextRange.InsertAfter(finalText);<br/>
Now you can change the taste of this segment of the text - such as font or color:
range.Font.Fill.ForeColor.RGB = settings.EmphasisColor.ToRgb();<br/>
range.Font.CopyFrom(settings.EmphasisFont ?? settings.CodeFont);<br/>
We have already discussed copying fonts, and the same problem with color. If you use the
ToArgb()
function which is already built in, you will get the color “inside out”. I had to implement the conversion manually:
public static int ToRgb( this Color color)<br/>
{<br/>
return (color.A << 24) + (color.B << 16) + (color.G << 8) + color.R;<br/>
}<br/>
Then it would be time to finish, only I want to make one warning: if you have made a paragraph of a certain color, then the next paragraph or piece of code will be
the same . Therefore, when building text from parts, first cache the default values, and apply them to each segment that you want to add.
Conclusion
Working with the VSTO infrastructure turned out to be quite simple, and the results of using add-in can soon be seen on my presentations at
Spbalt.net ,
Ineta ,
ActiveMesa and other organizations. And if you are suddenly interested in the project, the result of the add-in and the source code can be downloaded
here .
Notes
- ↑ By the way, this piece of code was used to implement the Prototype pattern in the add-in. Although now it seems to me that this is a bust -
MemberwiseClone()
could also be used. - ↑ In fact - no, it is impossible. IMHO, presentations need to be laid out in PDF and only in PDF (or do you think that Linux users are not interested in programming?), And when converting to PDF, the PP animation is lost. Therefore, the approach shown here is ideal for such groups as Spbalt.net where the materials of reports are only in PDF and are exhibited.
- ↑ The first extension of PP that I wrote was the visualization of neural networks. That was 3 years ago, even for the 2003 office.
- ↑ This phrase ( eating our own dogfood ) is used by Microsoft employees when they say that they use their own infrastructure for development.