views:

137

answers:

1

I am working on a PowerPoint 2007 VSTO add-in, and I am running in a small issue. The add-in adds sounds to the current slide using the following code:

var shape = slide.Shapes.AddMediaObject(soundFileLocation, 50, 50, 20, 20);

The resulting shape does have a sound, and can be played through the PowerPoint slide. My problem is that, given a reference to a shape that has been created that way, I would like to programmatically play the sound, but I can't find the way to do it. I tried

var soundEffect = shape.AnimationSettings.SoundEffect;
soundEffect.Play();

but this fails/crashes, and when I check soundEffect, its type is ppSoundNone.
Edit: got some partial success with

var shape = slide.Shapes.AddMediaObject(fileLocation, 50, 50, 20, 20);
shape.AnimationSettings.SoundEffect.ImportFromFile(fileLocation);

Doing this allows me to play the sound with:

var animationSettings = shape.AnimationSettings;
var soundEffect = shape.AnimationSettings.SoundEffect;
soundEffect.Play();

However there is one major issue; this works only for the last shape added. For some reason, shape.AnimationSettings.SoundEffect.ImportFromFile(fileLocation) seems to reset the SoundEffect property to ppSoundNone for the shapes previously created...

I would be surprised if this wasn't feasible, but I can't seem to find how - any help would be much appreciated!

+4  A: 

Sorry for the VBA, but it can easily be ported to C#. Here's what will work:

Sub addsound1()
    Dim ap As Presentation : Set ap = ActivePresentation
    Dim sl As Slide : Set sl = ap.Slides(1)
    Dim audioShape As Shape
    soundFileLocation = "C:\droid_scan.wav"
    Set audioShape = sl.Shapes.AddShape(msoShapeActionButtonSound, 100, 100, 50, 50)
    With audioShape.ActionSettings(ppMouseClick)
        .Action = ppActionNone
        .SoundEffect.ImportFromFile soundFileLocation
    End With
End Sub
Sub addsound2()
    Dim ap As Presentation : Set ap = ActivePresentation
    Dim sl As Slide : Set sl = ap.Slides(1)
    Dim audioShape As Shape
    soundFileLocation = "C:\droid_scan2.wav"
    Set audioShape = sl.Shapes.AddShape(msoShapeActionButtonSound, 50, 50, 50, 50)
    With audioShape.ActionSettings(ppMouseClick)
        .Action = ppActionNone
        .SoundEffect.ImportFromFile soundFileLocation
    End With
End Sub

Sub PlaySound1()
    Dim sh As Shape
    Set sh = ActivePresentation.Slides(1).Shapes(1)
    sh.ActionSettings(ppMouseClick).SoundEffect.Play
End Sub

Sub PlaySound2()
    Dim sh As Shape
    Set sh = ActivePresentation.Slides(1).Shapes(2)
    sh.ActionSettings(ppMouseClick).SoundEffect.Play
End Sub
Otaku
Thanks for pointing me in the direction of the TimeLine object. However, I am still stuck on how I trigger the sound to play in code. My understanding is that I need to get a SoundEffect object from somewhere, so that I can call SoundEffect.Play(). After using this code, the shape.AnimationSettings.SoundEffect still doesn't give me something I can Play(), and I don't quite understand how I can use the TimeLine to get something playable. Can you provide any guidance? The Ppt object is still very mysterious to me...
Mathias
@Mathias: How are you looking to play it other than how the `PlaySettings` above are set? For example, are you planning to go into SlideShowView and then after clicking the letter "P" it will play? Or are you looking to click on an object, like a shape, and then it play? Or are you trying to play it in Normal view? I'm trying to understand how you're expecting it and then I can update the code. One thing to note is that this isn't really a "media object" first and then an "animation" second - it's an animation first, so things like "Play" are not really what you'd expect.
Otaku
Sorry if my scenario wasn't clear. What I want to do is trigger playing from code, not through the presentation. Roughly, my add-in maintains a collection of the shapes that have sound, displayed in a listbox. When the user selects an item, I can access the shape, and I would like the sound to play. This is not in Slide Show mode, but in Normal mode (slide design). AddMediaObject creates clickable shapes that play the sound in Slide Show mode, I am looking for a way to play the sound attached to the shape in "design" mode, programmatically.
Mathias
@Mathias: Playing in Normal view - I don't know of a way to do this. The object model doesn't support this.
Otaku
ugh, that is bad news. I got it to work with narration, hoped the same would be feasible with "sound" shapes.
Mathias
@Otaku: let me try the question from a different angle. Once I created my shape, if I select it in Normal View, a new tab shows up in the Ribbon, "Options", with a group "Play" and a button "Preview Media". Would you know if it's feasible to invoke that command from the code? The Right-Click menu also shows that command. And thanks for all your input! I really appreciate it, especially so given the lack of documentation on PowerPoint.
Mathias
@Mathias: I looked briefly at the Custom Animation Pane to see if it could be invoked and the "Play" button called - I didn't have any succcess. But I'll research this some more to see if any other options may exist.
Otaku
@Mathias: Good find on your part! I've used that to test and seperating into to routines, it works well in Normal View each item, without changing the `.SoundEffect` property to `ppSoundNone`. See updates above.
Otaku
@Otaku: teamwork :) I wish I could upvote you more than once. However, there is still an issue, at least on my end. When I run this, it works great for the first shape, but when I run it a 2nd time, the 2nd shape gets the sound, but the 1st shape loses its SoundEffect, which reverts to ppSoundNone. I looked at the list of Effect in the MainSequence, and it seems to lose it as well. Are you observing the same issue, or is it a quirk with VSTO/interop?
Mathias
@Mathias: teamwork indeed! I quite like a difficult problem to solve together. So I've done so more research on this and a couple of things - there are 3 ways to "trigger" something. The old `AnimationSettings` (which is pre-PPT 2002), the new `TimeLine` animation engine and `ActionSettings`. Turns out that `ActionSettings` works just great. I've used the code above to set two different .wav files and play them both - works well. Note: this adds a `AutoShape` instead of a `MediaObject`. I just didn't see a point in adding the same .wav file twice to the same shape - but it can be used instead.
Otaku
Also, the code above is extremely verbose - just to demonstrate exactly what I was doing to test. It can be significantly reduced into just two functions.
Otaku
Sir, you are officially my hero for the week! It works great, and I can't thank you enough. I suspected that AnimationSetting was part of the problem, because it looks like it's being slowly deprecated, but without your help I don't think I would have found where I should look instead. I owe you my sanity for the week!
Mathias
More than happy to help with this - I learned something new as well!
Otaku