Experience Using VSTO for PowerPoint 2007

    I make a lot of presentations, and often I need to show the code "in parts", that is, show the train of thought in the process of sequential writing of the code. Unfortunately, PowerPoint is not configured for such purposes. Therefore, I decided to write an extension for PowerPoint 2007 that would automatically generate a progressive slide sequence of code and comments. Actually this will be the story.

    Idea


    First I’ll try to explain the idea. Do you have a piece of code, let's say this one [ 1 ]:
    public static T DeepCopy(this IPrototype obj)

    {

      T copy;

      using (MemoryStream stream = new MemoryStream())

      {

        BinaryFormatter formatter = new BinaryFormatter();

        formatter.Serialize(stream, obj);

        stream.Seek(0, SeekOrigin.Begin);

        copy = (T)formatter.Deserialize(stream);

        stream.Close();

      }

      return copy;

    }


    I would like to explain this code in parts on the slides. For example, you can initially show this:
    // создаем метод расширения
    public static T DeepCopy(this IPrototype obj)

    {


    And then, this one:
    // создаем метод расширения
    public static T DeepCopy(this IPrototype obj)

    {

      // создаем копию объекта
      T copy;


    Etc. It would seem that you can use the built-in animation [ 2 ], but this 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. But what if you need to hide not a paragraph or line, but only a couple of letters (for example, a keyword)? That's just for these purposes, I decided to write my second [ 3 ] add-in for PowerPoint.

    Interface


    Office add-ons are very easy to write: to do this, use the VSTO (Visual Studio Tools for Office) add-ons. The corresponding types of projects appear in the studio, from which I chose the PowerPoint 2007 Add-In:

    What is very pleasing is that our generated project is already ready for use. It works with F5 debugging , and which is nice - even if I'm not in the studio, the add-in remains in PowerPoint , which allows me to “eat my own dog food in my free time.” [ 4 ]
    Since the office uses tape controls (ribbons ), the studio supports working with these particular controls. There is even a special designer for creating ribbon elements:

    I needed only one button for the interface, which greatly 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 extension project, whether it be studio or office extensions. Usually I solve this problem using a separate assembly, but in this case I wanted to try to pee on WinForms, and for the interface I chose free (and pretty pretty) Krypton controls. Here's what this case looks like in the completed version:

    Not bad, is it? All this is free and available here . But how the window opens from the add-in 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 a predictable call ShowDialog().

    Work 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 that I received when initializing the add-in:

    public static Application App;

     

    private void OnStartup(object sender, EventArgs e)

    {

      App = Application;

      if (ApplicationStartedEvent != null)

        ApplicationStartedEvent(this, null);

    }


    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 with which the user works):

    var app = ThisAddIn.App;

    var p = app.ActivePresentation;


    Adding a new slide to your presentation is easy. Remember the types of layouts you can choose for a slide? So, here they are enum, so everything is very simple:

    Slide s = p.Slides.Add(

      1+p.Slides.Count, // вставить последним
      PpSlideLayout.ppLayoutText // одно большое текстовое поле
    );


    Further - even easier. The slide with our layout ppLayoutTexthas a title and a main text field. These objects are available in the Shapesslide collection (do not forget that collections are indexed from one, not from scratch). Here's an example of how to set the title text:
    var title = s.Shapes[1];

    title.TextFrame2.TextRange.Text = cff.ApplicationSettings.SlideTitle;


    By the way, I note that the use of the keyword is varvery helpful in the development. What is still noticeable is that when writing the entire add-in, I have never had to use a value missing, which is one of the main disadvantages when working with an office extension. In C # 4, there is of course no such problem.
    Here is an example of how to manipulate the properties of a text frame. In my case, I set the user-defined font and also remove the default fields and “shootouts”:
    var code = s.Shapes[2].TextFrame2.TextRange;

    code.ParagraphFormat.FirstLineIndent = 0;

    code.ParagraphFormat.Bullet.Visible = MsoTriState.msoFalse;

    code.Font.CopyFrom(cff.ApplicationSettings.CodeFont);

    code.ParagraphFormat.RightIndent = 0;

    code.ParagraphFormat.LeftIndent = 0;

    code.ParagraphFormat.SpaceBefore = 0;


    Note that fonts use the extension method. The problem is that Office uses its type Font2, and the conversion from of System.Drawing.Fontcourse is not defined. Also note that in the office, the types trueand falseare enums, so that you can set the values ​​"yes", "no" and "not set". Again, it is not difficult to determine the conversion from ours boolto office if you wish MsoTriState.

    Work with text


    As you might have guessed, the text is put into an object of type TextFrame2. When you add text to the frame, you get a link to the piece of code that you added:
    var range = textarea.TextFrame2.TextRange.InsertAfter(finalText);


    Now you can change the taste of this piece of text - such as font or color:
    range.Font.Fill.ForeColor.RGB = settings.EmphasisColor.ToRgb();

    range.Font.CopyFrom(settings.EmphasisFont ?? settings.CodeFont);


    We already discussed copying fonts, but with color the same problem. If you use a function ToArgb()that is already built-in, you get the color “inside out”. I had to implement the conversion manually:
    public static int ToRgb(this Color color)

    {

      return (color.A << 24) + (color.B << 16) + (color.G << 8) + color.R;

    }


    Here it’s time to finish already, but I want to make one warning: if you made a paragraph of a certain color, then the next paragraph or piece of code will be the same . Therefore, when building text from components, 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 very simple, and the results of using the add-in can soon be seen at my presentations at Spbalt.net , Ineta , ActiveMesa and other organizations. And if you suddenly became interested in the project, then the result of the add-in and the source code can be downloaded here .

    Notes


    1. 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 too much - you could use and MemberwiseClone().
    2. Actually - no, you can’t. IMHO, presentations need to be uploaded to PDF and only to PDF (or do you think that Linux users are not interested in programming?), And when converting to PDF, PP animation is lost. Therefore, the approach shown here is ideal for groups such as Spbalt.net where the presentation materials are only in PDF and exhibited.
    3. The first PP extension I wrote was visualization of neural networks. That was 3 years ago, back for the 2003 office.
    4. This phrase ( eating our own dogfood ) is used by Microsoft employees when they say that they use their own infrastructure for development.

    Also popular now: