How to: Share a PowerPoint Slidedeck

[This is preliminary documentation and is subject to change.]

Describes how to share a PowerPoint slide deck session in a Microsoft Lync 2013 Preview conversation by using the Microsoft Lync 2013 Preview API.

This topic describes how to create a shareable object that represents a PowerPoint deck, upload the shareable object to a conversation content bin, share it in a conversation, and then scroll through the slides. The sample application shown in Figure 1 is a Windows Forms application that implements the Lync 2013 Preview API to let a user manage PowerPoint sharing in a conversation.

Important note Important

PowerPoint sharing is not supported in Lync UI suppression mode.

This topic discusses the following concepts in PowerPoint sharing.

Figure 1 shows a sample conversation console application that lets a user manage virtual whiteboards on the sharing stage of a Microsoft Lync 2013 Preview conversation window.

Figure 1. Conversation whiteboard collaboration console.

PowerPoint presentation console slide navigation

When a user uploads and selects the Project Plan slide deck from the console shown in Figure 1, the slide deck is displayed in a Lync 2013 Preview conversation window sharing stage as shown in Figure 2.

Figure 2. PowerPoint deck shared in Lync 2013 conversation window.

Content stage with PowerPoint Deck shared

Before the logic in this topic runs in your application, a conversation must be active and you have registered an event callback method for the ContentSharingModalityActionAvailabilityChanged() event. The Microsoft.Lync.Model.Conversation.Sharing.ContentSharingModality is in a connected state. For information about starting a conversation that hosts content sharing, see How to: Start content sharing conversations.

Namespace declarations example

Add the following namespace declarations to your application

using Microsoft.Lync.Model;
using Microsoft.Lync.Model.Group;
using Microsoft.Lync.Model.Conversation;
using Microsoft.Lync.Model.Conversation.Sharing;
using System.Collections.Generic;


Field declarations example

Add the following class field declarations to your application.

        /// <summary>
        /// Lync client platform. The entry point to the API
        /// </summary>
        LyncClient _LyncClient;

        /// <summary>
        /// Represents a Lync conversation
        /// </summary>
        Conversation _conversation;

When the ModalityAction.CreateShareablePowerPointContent action is available, you can create the Microsoft.Lync.Model.Conversation.Sharing.ShareableContent object that encapsulates the PowerPoint deck you upload.

Upload a PowerPoint deck

  1. Verify that the ShareableContent object can be created by calling the Modality.CanInvoke method.

  2. Create the ShareableContent object by calling the ContentSharingModality.BeginCreateContentFromFile method.

  3. Upload the slide deck to the conversation by calling the ShareableContent.Upload method on the ShareableContent object.

  4. Register for the ShareableContent.ActionAvailabilityChanged event on the ShareableContent object.

Create and upload a PowerPoint deck example

The following example finishes first three steps of the previous procedure. The fourth step is completed in a following code example.

        /// <summary>
        /// Raised when the availability of an action on the content sharing modality changes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _sharingModality_ActionAvailabilityChanged(object sender, ModalityActionAvailabilityChangedEventArgs e)
        {
            this.Invoke(new AddAListItemDelegate(AddAListItem), new object[] { EventLog_ListBox, "Content Modality, Action changed " + e.Action.ToString() + " " + e.IsAvailable.ToString() });

            EnableDisableButtonDelegate d = new EnableDisableButtonDelegate(EnableDisableButton);
            switch (e.Action)
            {
                case ModalityAction.CreateShareablePowerPointContent:

                    try
                    {
                        if (((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).CanInvoke(ModalityAction.CreateShareablePowerPointContent))
                        {
                            ContentSharingModality c = (ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing];
                            string contentTitle = "ProjectPlan.pptx";
                            c.BeginCreateContentFromFile(
                                ShareableContentType.PowerPoint,
                                contentTitle,
                                "//MyShare/ProjectPlan.pptx",
                                false,
                                CreateShareableContentCallback,
                                c);
                        }
                    }
                    catch (InvalidStateException ise) { MessageBox.Show("Invalid state exception on BeginCreateContent " + ise.Message); }
                    catch (NotInitializedException) { MessageBox.Show("Not initialized exception on BeginCreateContent "); }

                    break;
                case ModalityAction.Accept:
                    _RemoteParticipantSharingModality = (ContentSharingModality)sender;
                    this.Invoke(d, new object[] { Accept_Button, e.IsAvailable });
                    break;
                case ModalityAction.Reject:
                    this.Invoke(d, new object[] {Reject_Button, e.IsAvailable });
                    break;
            }
        }


The following example is invoked on the API platform thread when the BeginCreateContentFromFile operation is complete. The [T:Microsoft.Lync.Model.Conversation.Sharing.ContentSharingModality.EndCreateContentFromFile(System.IAsyncResult)] method is called and then the PowerPoint deck is uploaded with call to the ShareableContent.Upload method.

Important note Important

The three exceptions that are in the following catch blocks are raised for conditions that you cannot test for before you call the Upload method. This is because other conversation participants may be uploading content to the common conversation content bin at the same time that the local user is uploading the PowerPoint deck. Another participant may have selected the same content title as selected by the local user or may have uploaded the maximum number of content bin items.

        /// <summary>
        /// Called by platform when ShareableContent object is created. 
        /// Uploads the PowerPoint slide deck to the conversation content bin
        /// where it is available to be shared (Presented)
        /// </summary>
        /// <param name="ar"></param>
        private void CreateShareableContentCallback(System.IAsyncResult ar)
        {
            try
            {
                ContentSharingModality shareModality = (ContentSharingModality)ar.AsyncState;
                ShareableContent sContent = shareModality.EndCreateContentFromFile(ar);
                sContent.Upload();
            }
            catch (MaxContentsExceededException) {
                MessageBox.Show("Content was not uploaded. You have reached the maximum number of content bin items");
            }
            catch (ContentTitleExistException) {
                MessageBox.Show("Content was not uploaded. Content title already exists");
            }
            catch (ContentTitleInvalidException) {
                MessageBox.Show("Content was not uploaded. Content title is not valid");
            }
        }


Register for the ShareableContent.ActionAvailabilityChanged event example

The following example registers event callback methods on the new SharingModality object events.

        /// <summary>
        /// Raised when an item is uploaded to the content bin
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _sharingModality_ContentAdded(object sender, ContentCollectionChangedEventArgs e)
        {
            e.Item.StateChanged += _ShareableContent_StateChanged;
            e.Item.ActionAvailabilityChanged += _ShareableContent_ActionAvailabilityChanged;
        }


Handle the ActionAvailabilityChanged event example

The following example enables or disables the content item sharing UI command buttons when the availability of actions on the Microsoft.Lync.Model.Conversation.Sharing.ShareableContent object changes.

        /// <summary>
        /// Raised when the availability of an action on a ShareableContent object changes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _ShareableContent_ActionAvailabilityChanged(object sender, ShareableContentActionAvailabilityChangedEventArgs e)
        {
            EnableDisableButtonDelegate d = new EnableDisableButtonDelegate(EnableDisableButton);
            switch (e.Action)
            {
                case ShareableContentAction.SaveAnnotation:
                    this.Invoke(d, new object[] { SaveAnnotations_Button, e.IsAvailable });
                    break;
                case ShareableContentAction.ClearAllAnnotations:
                    this.Invoke(d, new object[] { ClearAnnotations_Button, e.IsAvailable });
                    break;
                case ShareableContentAction.SyncWithPresenter:
                    this.Invoke(d, new object[] { SyncWithPresenter_Button, e.IsAvailable });
                    break;
                case ShareableContentAction.TakeOverAsPresenter:
                    this.Invoke(d, new object[] { TakeOverAsPresenter_Button, e.IsAvailable });
                    break;
                case ShareableContentAction.StopPresenting:
                    this.Invoke(d, new object[] { StopSharingContent_Button, e.IsAvailable });
                    break;
            }
        }

        private delegate void EnableDisableButtonDelegate(Button buttonToUpdate, Boolean newButtonEnableState);
        /// <summary>
        /// Enables or disables a UI button based on the actionAvailability
        /// </summary>
        /// <param name="buttonToUpdate"></param>
        /// <param name="newButtonEnableState"></param>
        private void EnableDisableButton(Button buttonToUpdate, Boolean newButtonEnableState)
        {
            buttonToUpdate.Enabled = newButtonEnableState;
        }


To share a whiteboard, call the ShareableContent.Present method on the content object that you want to share. If other content is being presented, it is displaced on the content sharing stage by the content sharing object that you called the Present method on.

Share a PowerPoint deck

  1. Iterate on the ContentSharingModality.ContentCollection property to find the Microsoft.Lync.Model.Conversation.Sharing.ShareableContent object whose ShareableContent.Title property matches the title that you want to share.

  2. Verify that the content can be presented by calling the ShareableContent.CanInvoke method.

  3. Share the content by calling the ShareableContent.Present method.

Code example

The following example presents the content item whose title is "Project Plan".

            //Iterate on content collection of conversation content sharing modality,
            //looking for the content whose title matches the string selected in the
            //list.
            foreach (ShareableContent sContent in ((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).ContentCollection)
            {
                if (sContent.Title == "Project Plan")
                {
                    int hrReason;
                    if (sContent.CanInvoke(ShareableContentAction.Present, out hrReason))
                    {
                        _ShareableContent = sContent;
                        sContent.Present();
                    }
                    else
                    {
                        MessageBox.Show("Cannot present whiteboard: " + hrReason.ToString());
                    }
                    break;
                }
            }


Scrolling through an active PowerPoint presentation in a conversation involves making one of three synchronous method calls. To go back one slide in the deck, call the PowerPointContent.GoBackward method. To go forward one slide, call the PowerPointContent.GoForward method. To return the view to meeting view mode, call the PowerPointContent.SyncWithPresenter method. These two methods are exposed on a sub-class of Microsoft.Lync.Model.Conversation.Sharing.ShareableContent so that you need to cast the ShareableContent object that encapsulates the active PowerPoint presentation into the Microsoft.Lync.Model.Conversation.Sharing.PowerPointContent class before you can scroll through the slides.

Important note Important

When the local user is a presenter in the conversation, scrolling behaves differently than when the user is an attendee. When a presenter is sharing a PowerPoint slide deck and scrolls the deck in either direction, it is scrolled for all conversation participants. If the local user is an attendee instead of a presenter, scrolling changes only the local view of the slide deck. When an attendee scrolls, the PowerPoint presentation is put into private viewing mode.

Scroll through PowerPoint slides

  1. Get the active content sharing object on the sharing stage of the conversation.

  2. Verify that the object is of type ShareableContentType.PowerPoint.

  3. Cast the shareable content object to the Microsoft.Lync.Model.Conversation.Sharing.PowerPointContent class.

  4. Call the PowerPointContent.GoForward, PowerPointContent.GoBackward, or PowerPointContent.SyncWithPresenter method.

Code example

The following examples scroll backward and forward one slide in the active PowerPoint slide deck.

        /// <summary>
        /// Scroll back one slide in the active PowerPoint slide deck.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GoBack_Button_Click(object sender, EventArgs e)
        {
            ShareableContent currentActiveContent = ((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).ActiveContent;
            if (currentActiveContent.Type == ShareableContentType.PowerPoint)
            {
                PowerPointContent ppc = currentActiveContent as PowerPointContent;
                ppc.GoBackward();
            }
        }

        /// <summary>
        /// Scroll forward one slide in the active PowerPoint slide deck.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GoForward_Button_Click(object sender, EventArgs e)
        {
            ShareableContent currentActiveContent = ((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).ActiveContent;
            if (currentActiveContent.Type == ShareableContentType.PowerPoint)
            {
                PowerPointContent ppc = currentActiveContent as PowerPointContent;
                ppc.GoForward();
            }

        }


When all these tasks are completed, the state of Lync 2013 Preview API objects are as described in the following table.

Lync 2013 Preview API conversation objects

Object

Description

State

Microsoft.Lync.Model.LyncClient

Client platform API entry point.

ClientState.SignedIn

Microsoft.Lync.Model.Conversation.Conversation

The content sharing conversation.

ConversationState.Active

Microsoft.Lync.Model.Conversation.Sharing.ContentSharingModality

The conversation content sharing modality.

NoteNote
Each participant in the active conversation exposes a collection of modalities that include a content sharing modality. Each of these content sharing modality objects is also connected.

ModalityState.Connected

Microsoft.Lync.Model.Conversation.Sharing.ShareableContent

The PowerPoint deck that is uploaded and shared in the conversation.

ShareableContentState.Active

NoteNote
If you are no longer sharing the PowerPoint deck then the status is ShareableContentState.Online

Community Additions

Show:
© 2014 Microsoft