How to: Save and clear whiteboard annotations
Learn how to save and clear annotations made to a whiteboard in a Lync 2013 conversation by using Microsoft Lync 2013 SDK.
Applies to: Lync 2013 | Lync Server 2013
In this article |
Whiteboard annotations overview
Learn how to save an image of an annotated meeting whiteboard as an .xps or .png file. The sample application shown in figure 1 is a Windows Forms application that implements the Lync 2013 API to let a user save annotations on shared content.
Important |
---|
Conversation content annotation saving and clearing is not supported in Lync UI suppression mode. |
Figure 1 shows a sample conversation console application that lets a user attach files to a Microsoft Lync 2013 conversation.
Prerequisites
The prerequisites for saving and clearing annotations are as follows:
Microsoft Lync 2013 must be installed and running on the development computer.
You must have sign-in credentials for Microsoft Lync Server 2013.
Microsoft Lync 2013 SDK must be installed on the development computer.
Core concepts to know
Understanding the following concepts is essential to using content sharing conversions in an application.
Topic |
Description |
---|---|
Learn about the nature of shareable content in a Lync 2013 conversation and what content sharing feature that Microsoft Lync 2013 SDK lets you build into your application. |
|
Learn about the Lync 2013 conversation modality that is used to administer meeting content in an online meeting. |
|
Learn how to share a whiteboard collaboration session in a Lync 2013 conversation by using Microsoft Lync 2013 SDK. |
First steps
Before the logic in this topic runs in your application, a conversation must be active and referenced by the class field _conversation. You have registered an event callback method for the ContentSharingModalityActionAvailabilityChanged() event. The Microsoft.Lync.Model.Conversation.Sharing.ContentSharingModality is in a connected state. At least one shareable content item is uploaded to the conversation and annotated. For information about starting a conversation that hosts content sharing, see How to: Start a content sharing conversation.
Code example: Namespace declarations
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;
Code example: Field declarations
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;
Save content annotations
You can save the annotations that are made to any content in the content bin whether it's currently active or not. To save the annotations made to an Microsoft.Lync.Model.Conversation.Sharing.ShareableContent object, obtain the path and file name from the user and the annotation image file format to be applied to the saved image.
Tip |
---|
Be sure to verify that the annotation save path supplied by the user exists before attempting to save the annotations to a file. |
Code example: Save annotations
The following example saves the annotations made to the active shared content locally as a .png image.
/// <summary>
/// If content stage item is a Whiteboard, saves whiteboard annotations.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SaveAnnotations_Button_Click(object sender, EventArgs e)
{
ContentSharingModality csm = (ContentSharingModality)_conversation
.Modalities[ModalityTypes.ContentSharing];
int hrReason;
if (csm.ActiveContent.CanInvoke(ShareableContentAction.SaveAnnotation, out hrReason))
{
DirectoryInfo dirInfo = new DirectoryInfo(@"c:\users\public\");
if (dirInfo.Exists)
{
csm.ActiveContent.SaveAnnotation(
@"c:\users\public\"
+ csm.ActiveContent.Title
+ ".png"
, ContentSavingFileType.PNG);
}
}
else
{
MessageBox.Show("Annotations cannot be saved for " + _ShareableContent.Title);
}
}
Clear content annotations
You can clear the annotations that are made to any content in the content bin whether it's currently active or not. To clear the annotations made to an Microsoft.Lync.Model.Conversation.Sharing.ShareableContent object, call the ShareableContent.ClearAllAnnotations method on the object.
Code example: Clear all annotations
The following example clears all annotations on the active shared content.
int hrReason;
if (((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).ActiveContent.CanInvoke(ShareableContentAction.ClearAllAnnotations, out hrReason))
{
((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).ActiveContent.ClearAllAnnotations();
}
Code examples: Quick meeting console
The following example declares a Windows Form that presents a meeting content console application. A user can start a conversation and manage the content that is shared on the conversation content stage using this example application.
namespace ContentSharing
{
partial class ContentSharing_Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.ClientState_Label = new System.Windows.Forms.Label();
this.ClientStateString_Label = new System.Windows.Forms.Label();
this.Contact_ListBox = new System.Windows.Forms.ListBox();
this.ConversationActions_Group = new System.Windows.Forms.GroupBox();
this.EndConversation_Button = new System.Windows.Forms.Button();
this.Start_Button = new System.Windows.Forms.Button();
this.ContactList_Label = new System.Windows.Forms.Label();
this.Content_Listbox = new System.Windows.Forms.ListBox();
this.label1 = new System.Windows.Forms.Label();
this.ShareableContentTitle_Textbox = new System.Windows.Forms.TextBox();
this.ShareWhiteboard_Button = new System.Windows.Forms.Button();
this.ContentShare_Button = new System.Windows.Forms.Button();
this.StopSharingContent_Button = new System.Windows.Forms.Button();
this.PickContentItemPath_OpenFileDialog = new System.Windows.Forms.OpenFileDialog();
this.PickAPowerPoint_Button = new System.Windows.Forms.Button();
this.PickNativeFile_Button = new System.Windows.Forms.Button();
this.DownloadAttachment_Button = new System.Windows.Forms.Button();
this.Accept_Button = new System.Windows.Forms.Button();
this.Reject_Button = new System.Windows.Forms.Button();
this.ModalityConnectedState_Panel = new System.Windows.Forms.Panel();
this.ActiveContent_Label = new System.Windows.Forms.Label();
this.ClearAnnotations_Button = new System.Windows.Forms.Button();
this.SaveAnnotations_Button = new System.Windows.Forms.Button();
this.SyncWithPresenter_Button = new System.Windows.Forms.Button();
this.TakeOverAsPresenter_Button = new System.Windows.Forms.Button();
this.GoBack_Button = new System.Windows.Forms.Button();
this.GoForward_Button = new System.Windows.Forms.Button();
this.StartConversation_Group = new System.Windows.Forms.GroupBox();
this.ModalityState_Label = new System.Windows.Forms.Label();
this.ContentBin_Groupbox = new System.Windows.Forms.GroupBox();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.AddNativeFile_Button = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.AddPowerPoint_Button = new System.Windows.Forms.Button();
this.ContentItem_GroupBox = new System.Windows.Forms.GroupBox();
this.label2 = new System.Windows.Forms.Label();
this.RefreshContent_Button = new System.Windows.Forms.Button();
this.RemoveFromBin_Button = new System.Windows.Forms.Button();
this.SharingInvitation_Groupbox = new System.Windows.Forms.GroupBox();
this.DownloadFolderBrowser_FolderBrowser = new System.Windows.Forms.FolderBrowserDialog();
this.SetBusy_Button = new System.Windows.Forms.Button();
this.Alerts_Button = new System.Windows.Forms.Button();
this.ConversationActions_Group.SuspendLayout();
this.StartConversation_Group.SuspendLayout();
this.ContentBin_Groupbox.SuspendLayout();
this.groupBox3.SuspendLayout();
this.groupBox2.SuspendLayout();
this.groupBox1.SuspendLayout();
this.ContentItem_GroupBox.SuspendLayout();
this.SharingInvitation_Groupbox.SuspendLayout();
this.SuspendLayout();
//
// ClientState_Label
//
this.ClientState_Label.AutoSize = true;
this.ClientState_Label.Location = new System.Drawing.Point(16, 7);
this.ClientState_Label.Name = "ClientState_Label";
this.ClientState_Label.Size = new System.Drawing.Size(64, 13);
this.ClientState_Label.TabIndex = 0;
this.ClientState_Label.Text = "Client State:";
//
// ClientStateString_Label
//
this.ClientStateString_Label.AutoSize = true;
this.ClientStateString_Label.Location = new System.Drawing.Point(115, 9);
this.ClientStateString_Label.Name = "ClientStateString_Label";
this.ClientStateString_Label.Size = new System.Drawing.Size(58, 13);
this.ClientStateString_Label.TabIndex = 1;
this.ClientStateString_Label.Text = "Signed out";
//
// Contact_ListBox
//
this.Contact_ListBox.FormattingEnabled = true;
this.Contact_ListBox.HorizontalScrollbar = true;
this.Contact_ListBox.Location = new System.Drawing.Point(6, 37);
this.Contact_ListBox.Name = "Contact_ListBox";
this.Contact_ListBox.SelectionMode = System.Windows.Forms.SelectionMode.MultiSimple;
this.Contact_ListBox.Size = new System.Drawing.Size(204, 69);
this.Contact_ListBox.TabIndex = 2;
//
// ConversationActions_Group
//
this.ConversationActions_Group.Controls.Add(this.EndConversation_Button);
this.ConversationActions_Group.Controls.Add(this.Start_Button);
this.ConversationActions_Group.Location = new System.Drawing.Point(6, 119);
this.ConversationActions_Group.Name = "ConversationActions_Group";
this.ConversationActions_Group.Size = new System.Drawing.Size(204, 83);
this.ConversationActions_Group.TabIndex = 13;
this.ConversationActions_Group.TabStop = false;
this.ConversationActions_Group.Text = "Start a conversation";
//
// EndConversation_Button
//
this.EndConversation_Button.Enabled = false;
this.EndConversation_Button.Location = new System.Drawing.Point(16, 52);
this.EndConversation_Button.Name = "EndConversation_Button";
this.EndConversation_Button.Size = new System.Drawing.Size(163, 23);
this.EndConversation_Button.TabIndex = 0;
this.EndConversation_Button.Text = "End";
this.EndConversation_Button.UseVisualStyleBackColor = true;
this.EndConversation_Button.Click += new System.EventHandler(this.EndConversation_Button_Click);
//
// Start_Button
//
this.Start_Button.Enabled = false;
this.Start_Button.Location = new System.Drawing.Point(16, 23);
this.Start_Button.Name = "Start_Button";
this.Start_Button.Size = new System.Drawing.Size(163, 23);
this.Start_Button.TabIndex = 16;
this.Start_Button.Text = "Start";
this.Start_Button.UseVisualStyleBackColor = true;
this.Start_Button.Click += new System.EventHandler(this.Start_Button_Click);
//
// ContactList_Label
//
this.ContactList_Label.AutoSize = true;
this.ContactList_Label.Location = new System.Drawing.Point(6, 21);
this.ContactList_Label.Name = "ContactList_Label";
this.ContactList_Label.Size = new System.Drawing.Size(92, 13);
this.ContactList_Label.TabIndex = 20;
this.ContactList_Label.Text = "People in Meeting";
//
// Content_Listbox
//
this.Content_Listbox.FormattingEnabled = true;
this.Content_Listbox.Location = new System.Drawing.Point(24, 97);
this.Content_Listbox.Name = "Content_Listbox";
this.Content_Listbox.Size = new System.Drawing.Size(175, 82);
this.Content_Listbox.TabIndex = 21;
this.Content_Listbox.SelectedIndexChanged += new System.EventHandler(this.Content_Listbox_SelectedIndexChanged);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(10, 16);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(113, 13);
this.label1.TabIndex = 29;
this.label1.Text = "New Whiteboard Title:";
//
// ShareableContentTitle_Textbox
//
this.ShareableContentTitle_Textbox.Location = new System.Drawing.Point(20, 32);
this.ShareableContentTitle_Textbox.Name = "ShareableContentTitle_Textbox";
this.ShareableContentTitle_Textbox.Size = new System.Drawing.Size(96, 20);
this.ShareableContentTitle_Textbox.TabIndex = 30;
//
// ShareWhiteboard_Button
//
this.ShareWhiteboard_Button.Location = new System.Drawing.Point(17, 58);
this.ShareWhiteboard_Button.Name = "ShareWhiteboard_Button";
this.ShareWhiteboard_Button.Size = new System.Drawing.Size(163, 23);
this.ShareWhiteboard_Button.TabIndex = 32;
this.ShareWhiteboard_Button.Text = "Add Whiteboard";
this.ShareWhiteboard_Button.UseVisualStyleBackColor = true;
this.ShareWhiteboard_Button.Click += new System.EventHandler(this.ShareNewContent_Button_Click);
//
// ContentShare_Button
//
this.ContentShare_Button.Enabled = false;
this.ContentShare_Button.Location = new System.Drawing.Point(25, 257);
this.ContentShare_Button.Name = "ContentShare_Button";
this.ContentShare_Button.Size = new System.Drawing.Size(174, 23);
this.ContentShare_Button.TabIndex = 34;
this.ContentShare_Button.Text = "Share Content";
this.ContentShare_Button.UseVisualStyleBackColor = true;
this.ContentShare_Button.Click += new System.EventHandler(this.ContentShare_Button_Click);
//
// StopSharingContent_Button
//
this.StopSharingContent_Button.Enabled = false;
this.StopSharingContent_Button.Location = new System.Drawing.Point(25, 282);
this.StopSharingContent_Button.Name = "StopSharingContent_Button";
this.StopSharingContent_Button.Size = new System.Drawing.Size(174, 23);
this.StopSharingContent_Button.TabIndex = 35;
this.StopSharingContent_Button.Text = "Stop Sharing";
this.StopSharingContent_Button.UseVisualStyleBackColor = true;
this.StopSharingContent_Button.Click += new System.EventHandler(this.StopSharingContent_Button_Click);
//
// PickContentItemPath_OpenFileDialog
//
this.PickContentItemPath_OpenFileDialog.FileName = "ABriefHistoryofThyme.pptx";
this.PickContentItemPath_OpenFileDialog.InitialDirectory = "Libraries\\Documents";
//
// PickAPowerPoint_Button
//
this.PickAPowerPoint_Button.Location = new System.Drawing.Point(13, 19);
this.PickAPowerPoint_Button.Name = "PickAPowerPoint_Button";
this.PickAPowerPoint_Button.Size = new System.Drawing.Size(163, 23);
this.PickAPowerPoint_Button.TabIndex = 36;
this.PickAPowerPoint_Button.Text = "Pick PowerPoint Deck";
this.PickAPowerPoint_Button.UseVisualStyleBackColor = true;
this.PickAPowerPoint_Button.Click += new System.EventHandler(this.PickAPowerPoint_Button_Click);
//
// PickNativeFile_Button
//
this.PickNativeFile_Button.Location = new System.Drawing.Point(12, 19);
this.PickNativeFile_Button.Name = "PickNativeFile_Button";
this.PickNativeFile_Button.Size = new System.Drawing.Size(163, 23);
this.PickNativeFile_Button.TabIndex = 37;
this.PickNativeFile_Button.Text = "Pick Attachment";
this.PickNativeFile_Button.UseVisualStyleBackColor = true;
this.PickNativeFile_Button.Click += new System.EventHandler(this.PickNativeFile_Button_Click);
//
// DownloadAttachment_Button
//
this.DownloadAttachment_Button.Enabled = false;
this.DownloadAttachment_Button.Location = new System.Drawing.Point(25, 382);
this.DownloadAttachment_Button.Name = "DownloadAttachment_Button";
this.DownloadAttachment_Button.Size = new System.Drawing.Size(175, 23);
this.DownloadAttachment_Button.TabIndex = 38;
this.DownloadAttachment_Button.Text = "Download Attachment";
this.DownloadAttachment_Button.UseVisualStyleBackColor = true;
this.DownloadAttachment_Button.Click += new System.EventHandler(this.DownloadAttachment_Button_Click);
//
// Accept_Button
//
this.Accept_Button.Enabled = false;
this.Accept_Button.Location = new System.Drawing.Point(8, 27);
this.Accept_Button.Name = "Accept_Button";
this.Accept_Button.Size = new System.Drawing.Size(99, 23);
this.Accept_Button.TabIndex = 39;
this.Accept_Button.Text = "Acccept";
this.Accept_Button.UseVisualStyleBackColor = true;
this.Accept_Button.Click += new System.EventHandler(this.Accept_Button_Click);
//
// Reject_Button
//
this.Reject_Button.Enabled = false;
this.Reject_Button.Location = new System.Drawing.Point(122, 27);
this.Reject_Button.Name = "Reject_Button";
this.Reject_Button.Size = new System.Drawing.Size(99, 23);
this.Reject_Button.TabIndex = 40;
this.Reject_Button.Text = "Reject";
this.Reject_Button.UseVisualStyleBackColor = true;
this.Reject_Button.Click += new System.EventHandler(this.Reject_Button_Click);
//
// ModalityConnectedState_Panel
//
this.ModalityConnectedState_Panel.BackColor = System.Drawing.Color.Red;
this.ModalityConnectedState_Panel.Location = new System.Drawing.Point(178, 377);
this.ModalityConnectedState_Panel.Name = "ModalityConnectedState_Panel";
this.ModalityConnectedState_Panel.Size = new System.Drawing.Size(35, 13);
this.ModalityConnectedState_Panel.TabIndex = 41;
//
// ActiveContent_Label
//
this.ActiveContent_Label.AutoSize = true;
this.ActiveContent_Label.Location = new System.Drawing.Point(18, 33);
this.ActiveContent_Label.Name = "ActiveContent_Label";
this.ActiveContent_Label.Size = new System.Drawing.Size(80, 13);
this.ActiveContent_Label.TabIndex = 43;
this.ActiveContent_Label.Text = "Active Content:";
//
// ClearAnnotations_Button
//
this.ClearAnnotations_Button.Enabled = false;
this.ClearAnnotations_Button.Location = new System.Drawing.Point(25, 307);
this.ClearAnnotations_Button.Name = "ClearAnnotations_Button";
this.ClearAnnotations_Button.Size = new System.Drawing.Size(175, 23);
this.ClearAnnotations_Button.TabIndex = 44;
this.ClearAnnotations_Button.Text = "Clear Annotations";
this.ClearAnnotations_Button.UseVisualStyleBackColor = true;
this.ClearAnnotations_Button.Click += new System.EventHandler(this.ClearAnnotations_Button_Click);
//
// SaveAnnotations_Button
//
this.SaveAnnotations_Button.Enabled = false;
this.SaveAnnotations_Button.Location = new System.Drawing.Point(25, 332);
this.SaveAnnotations_Button.Name = "SaveAnnotations_Button";
this.SaveAnnotations_Button.Size = new System.Drawing.Size(174, 23);
this.SaveAnnotations_Button.TabIndex = 45;
this.SaveAnnotations_Button.Text = "Save Annotations";
this.SaveAnnotations_Button.UseVisualStyleBackColor = true;
this.SaveAnnotations_Button.Click += new System.EventHandler(this.SaveAnnotations_Button_Click);
//
// SyncWithPresenter_Button
//
this.SyncWithPresenter_Button.Enabled = false;
this.SyncWithPresenter_Button.Location = new System.Drawing.Point(25, 407);
this.SyncWithPresenter_Button.Name = "SyncWithPresenter_Button";
this.SyncWithPresenter_Button.Size = new System.Drawing.Size(174, 23);
this.SyncWithPresenter_Button.TabIndex = 46;
this.SyncWithPresenter_Button.Text = "Return to meeting view";
this.SyncWithPresenter_Button.UseVisualStyleBackColor = true;
this.SyncWithPresenter_Button.Click += new System.EventHandler(this.SyncWithPresenter_Button_Click);
//
// TakeOverAsPresenter_Button
//
this.TakeOverAsPresenter_Button.Enabled = false;
this.TakeOverAsPresenter_Button.Location = new System.Drawing.Point(25, 357);
this.TakeOverAsPresenter_Button.Name = "TakeOverAsPresenter_Button";
this.TakeOverAsPresenter_Button.Size = new System.Drawing.Size(175, 23);
this.TakeOverAsPresenter_Button.TabIndex = 47;
this.TakeOverAsPresenter_Button.Text = "Take Over as Presenter";
this.TakeOverAsPresenter_Button.UseVisualStyleBackColor = true;
this.TakeOverAsPresenter_Button.Click += new System.EventHandler(this.TakeOverAsPresenter_Button_Click);
//
// GoBack_Button
//
this.GoBack_Button.Enabled = false;
this.GoBack_Button.Location = new System.Drawing.Point(24, 439);
this.GoBack_Button.Name = "GoBack_Button";
this.GoBack_Button.Size = new System.Drawing.Size(75, 23);
this.GoBack_Button.TabIndex = 48;
this.GoBack_Button.Text = "<<";
this.GoBack_Button.UseVisualStyleBackColor = true;
this.GoBack_Button.Click += new System.EventHandler(this.GoBack_Button_Click_1);
//
// GoForward_Button
//
this.GoForward_Button.Enabled = false;
this.GoForward_Button.Location = new System.Drawing.Point(124, 439);
this.GoForward_Button.Name = "GoForward_Button";
this.GoForward_Button.Size = new System.Drawing.Size(75, 23);
this.GoForward_Button.TabIndex = 49;
this.GoForward_Button.Text = ">>";
this.GoForward_Button.UseVisualStyleBackColor = true;
this.GoForward_Button.Click += new System.EventHandler(this.GoForward_Button_Click_1);
//
// StartConversation_Group
//
this.StartConversation_Group.Controls.Add(this.Contact_ListBox);
this.StartConversation_Group.Controls.Add(this.ConversationActions_Group);
this.StartConversation_Group.Controls.Add(this.ContactList_Label);
this.StartConversation_Group.Location = new System.Drawing.Point(12, 48);
this.StartConversation_Group.Name = "StartConversation_Group";
this.StartConversation_Group.Size = new System.Drawing.Size(226, 215);
this.StartConversation_Group.TabIndex = 50;
this.StartConversation_Group.TabStop = false;
this.StartConversation_Group.Text = "Conversation";
//
// ModalityState_Label
//
this.ModalityState_Label.AutoSize = true;
this.ModalityState_Label.Location = new System.Drawing.Point(7, 377);
this.ModalityState_Label.Name = "ModalityState_Label";
this.ModalityState_Label.Size = new System.Drawing.Size(165, 13);
this.ModalityState_Label.TabIndex = 42;
this.ModalityState_Label.Text = "State of Content Sharing Modality";
//
// ContentBin_Groupbox
//
this.ContentBin_Groupbox.Controls.Add(this.ModalityState_Label);
this.ContentBin_Groupbox.Controls.Add(this.ModalityConnectedState_Panel);
this.ContentBin_Groupbox.Controls.Add(this.groupBox3);
this.ContentBin_Groupbox.Controls.Add(this.groupBox2);
this.ContentBin_Groupbox.Controls.Add(this.groupBox1);
this.ContentBin_Groupbox.Location = new System.Drawing.Point(12, 286);
this.ContentBin_Groupbox.Name = "ContentBin_Groupbox";
this.ContentBin_Groupbox.Size = new System.Drawing.Size(226, 424);
this.ContentBin_Groupbox.TabIndex = 52;
this.ContentBin_Groupbox.TabStop = false;
this.ContentBin_Groupbox.Text = "Content Bin Management";
//
// groupBox3
//
this.groupBox3.Controls.Add(this.ShareableContentTitle_Textbox);
this.groupBox3.Controls.Add(this.label1);
this.groupBox3.Controls.Add(this.ShareWhiteboard_Button);
this.groupBox3.Location = new System.Drawing.Point(10, 33);
this.groupBox3.Name = "groupBox3";
this.groupBox3.Size = new System.Drawing.Size(200, 100);
this.groupBox3.TabIndex = 44;
this.groupBox3.TabStop = false;
this.groupBox3.Text = "Whiteboard";
//
// groupBox2
//
this.groupBox2.Controls.Add(this.PickNativeFile_Button);
this.groupBox2.Controls.Add(this.AddNativeFile_Button);
this.groupBox2.Location = new System.Drawing.Point(9, 256);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(200, 86);
this.groupBox2.TabIndex = 43;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Attachment";
//
// AddNativeFile_Button
//
this.AddNativeFile_Button.Location = new System.Drawing.Point(12, 48);
this.AddNativeFile_Button.Name = "AddNativeFile_Button";
this.AddNativeFile_Button.Size = new System.Drawing.Size(163, 23);
this.AddNativeFile_Button.TabIndex = 39;
this.AddNativeFile_Button.Text = "Upload Attachment";
this.AddNativeFile_Button.UseVisualStyleBackColor = true;
this.AddNativeFile_Button.Click += new System.EventHandler(this.UploadNativeFile_Button_Click);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.PickAPowerPoint_Button);
this.groupBox1.Controls.Add(this.AddPowerPoint_Button);
this.groupBox1.Location = new System.Drawing.Point(9, 156);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(201, 86);
this.groupBox1.TabIndex = 42;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "PowerPoint";
//
// AddPowerPoint_Button
//
this.AddPowerPoint_Button.Location = new System.Drawing.Point(13, 46);
this.AddPowerPoint_Button.Name = "AddPowerPoint_Button";
this.AddPowerPoint_Button.Size = new System.Drawing.Size(163, 23);
this.AddPowerPoint_Button.TabIndex = 38;
this.AddPowerPoint_Button.Text = "Upload PowerPoint";
this.AddPowerPoint_Button.UseVisualStyleBackColor = true;
this.AddPowerPoint_Button.Click += new System.EventHandler(this.AddPowerPoint_Button_Click);
//
// ContentItem_GroupBox
//
this.ContentItem_GroupBox.Controls.Add(this.label2);
this.ContentItem_GroupBox.Controls.Add(this.RefreshContent_Button);
this.ContentItem_GroupBox.Controls.Add(this.RemoveFromBin_Button);
this.ContentItem_GroupBox.Controls.Add(this.Content_Listbox);
this.ContentItem_GroupBox.Controls.Add(this.ContentShare_Button);
this.ContentItem_GroupBox.Controls.Add(this.StopSharingContent_Button);
this.ContentItem_GroupBox.Controls.Add(this.GoForward_Button);
this.ContentItem_GroupBox.Controls.Add(this.DownloadAttachment_Button);
this.ContentItem_GroupBox.Controls.Add(this.GoBack_Button);
this.ContentItem_GroupBox.Controls.Add(this.ActiveContent_Label);
this.ContentItem_GroupBox.Controls.Add(this.TakeOverAsPresenter_Button);
this.ContentItem_GroupBox.Controls.Add(this.ClearAnnotations_Button);
this.ContentItem_GroupBox.Controls.Add(this.SyncWithPresenter_Button);
this.ContentItem_GroupBox.Controls.Add(this.SaveAnnotations_Button);
this.ContentItem_GroupBox.Location = new System.Drawing.Point(252, 149);
this.ContentItem_GroupBox.Name = "ContentItem_GroupBox";
this.ContentItem_GroupBox.Size = new System.Drawing.Size(219, 561);
this.ContentItem_GroupBox.TabIndex = 53;
this.ContentItem_GroupBox.TabStop = false;
this.ContentItem_GroupBox.Text = "Shared Content Actions";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(21, 79);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(103, 13);
this.label2.TabIndex = 56;
this.label2.Text = "Meeting Content Bin";
//
// RefreshContent_Button
//
this.RefreshContent_Button.Location = new System.Drawing.Point(24, 226);
this.RefreshContent_Button.Name = "RefreshContent_Button";
this.RefreshContent_Button.Size = new System.Drawing.Size(175, 25);
this.RefreshContent_Button.TabIndex = 55;
this.RefreshContent_Button.Text = "Refresh Content List";
this.RefreshContent_Button.UseVisualStyleBackColor = true;
this.RefreshContent_Button.Click += new System.EventHandler(this.RefreshContent_Button_Click);
//
// RemoveFromBin_Button
//
this.RemoveFromBin_Button.Location = new System.Drawing.Point(24, 197);
this.RemoveFromBin_Button.Name = "RemoveFromBin_Button";
this.RemoveFromBin_Button.Size = new System.Drawing.Size(175, 23);
this.RemoveFromBin_Button.TabIndex = 50;
this.RemoveFromBin_Button.Text = "Remove";
this.RemoveFromBin_Button.UseVisualStyleBackColor = true;
this.RemoveFromBin_Button.Click += new System.EventHandler(this.RemoveFromBin_Button_Click);
//
// SharingInvitation_Groupbox
//
this.SharingInvitation_Groupbox.Controls.Add(this.Reject_Button);
this.SharingInvitation_Groupbox.Controls.Add(this.Accept_Button);
this.SharingInvitation_Groupbox.Location = new System.Drawing.Point(244, 48);
this.SharingInvitation_Groupbox.Name = "SharingInvitation_Groupbox";
this.SharingInvitation_Groupbox.Size = new System.Drawing.Size(227, 60);
this.SharingInvitation_Groupbox.TabIndex = 54;
this.SharingInvitation_Groupbox.TabStop = false;
this.SharingInvitation_Groupbox.Text = "Content Sharing Invitation";
//
// DownloadFolderBrowser_FolderBrowser
//
this.DownloadFolderBrowser_FolderBrowser.RootFolder = System.Environment.SpecialFolder.CommonDocuments;
this.DownloadFolderBrowser_FolderBrowser.SelectedPath = "C:\\Users\\Public";
//
// SetBusy_Button
//
this.SetBusy_Button.Location = new System.Drawing.Point(244, 9);
this.SetBusy_Button.Name = "SetBusy_Button";
this.SetBusy_Button.Size = new System.Drawing.Size(142, 23);
this.SetBusy_Button.TabIndex = 55;
this.SetBusy_Button.Text = "Set In Meeting status";
this.SetBusy_Button.UseVisualStyleBackColor = true;
this.SetBusy_Button.Click += new System.EventHandler(this.SetBusy_Button_Click);
//
// Alerts_Button
//
this.Alerts_Button.Location = new System.Drawing.Point(392, 9);
this.Alerts_Button.Name = "Alerts_Button";
this.Alerts_Button.Size = new System.Drawing.Size(75, 23);
this.Alerts_Button.TabIndex = 56;
this.Alerts_Button.Text = "Alerts";
this.Alerts_Button.UseVisualStyleBackColor = true;
this.Alerts_Button.Click += new System.EventHandler(this.Alerts_Button_Click);
//
// ContentSharing_Form
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(485, 728);
this.Controls.Add(this.Alerts_Button);
this.Controls.Add(this.SetBusy_Button);
this.Controls.Add(this.SharingInvitation_Groupbox);
this.Controls.Add(this.ContentItem_GroupBox);
this.Controls.Add(this.ContentBin_Groupbox);
this.Controls.Add(this.StartConversation_Group);
this.Controls.Add(this.ClientStateString_Label);
this.Controls.Add(this.ClientState_Label);
this.Name = "ContentSharing_Form";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Quick Meeting Console";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.ContentSharing_Form_FormClosing);
this.Load += new System.EventHandler(this.ContentSharing_Form_Load);
this.ConversationActions_Group.ResumeLayout(false);
this.StartConversation_Group.ResumeLayout(false);
this.StartConversation_Group.PerformLayout();
this.ContentBin_Groupbox.ResumeLayout(false);
this.ContentBin_Groupbox.PerformLayout();
this.groupBox3.ResumeLayout(false);
this.groupBox3.PerformLayout();
this.groupBox2.ResumeLayout(false);
this.groupBox1.ResumeLayout(false);
this.ContentItem_GroupBox.ResumeLayout(false);
this.ContentItem_GroupBox.PerformLayout();
this.SharingInvitation_Groupbox.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label ClientState_Label;
private System.Windows.Forms.Label ClientStateString_Label;
private System.Windows.Forms.ListBox Contact_ListBox;
private System.Windows.Forms.GroupBox ConversationActions_Group;
private System.Windows.Forms.Button EndConversation_Button;
private System.Windows.Forms.Button Start_Button;
private System.Windows.Forms.Label ContactList_Label;
private System.Windows.Forms.ListBox Content_Listbox;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox ShareableContentTitle_Textbox;
private System.Windows.Forms.Button ShareWhiteboard_Button;
private System.Windows.Forms.Button ContentShare_Button;
private System.Windows.Forms.Button StopSharingContent_Button;
private System.Windows.Forms.OpenFileDialog PickContentItemPath_OpenFileDialog;
private System.Windows.Forms.Button PickAPowerPoint_Button;
private System.Windows.Forms.Button PickNativeFile_Button;
private System.Windows.Forms.Button DownloadAttachment_Button;
private System.Windows.Forms.Button Accept_Button;
private System.Windows.Forms.Button Reject_Button;
private System.Windows.Forms.Panel ModalityConnectedState_Panel;
private System.Windows.Forms.Label ActiveContent_Label;
private System.Windows.Forms.Button ClearAnnotations_Button;
private System.Windows.Forms.Button SaveAnnotations_Button;
private System.Windows.Forms.Button SyncWithPresenter_Button;
private System.Windows.Forms.Button TakeOverAsPresenter_Button;
private System.Windows.Forms.Button GoBack_Button;
private System.Windows.Forms.Button GoForward_Button;
private System.Windows.Forms.GroupBox StartConversation_Group;
private System.Windows.Forms.GroupBox ContentBin_Groupbox;
private System.Windows.Forms.Label ModalityState_Label;
private System.Windows.Forms.GroupBox ContentItem_GroupBox;
private System.Windows.Forms.GroupBox SharingInvitation_Groupbox;
private System.Windows.Forms.Button RemoveFromBin_Button;
private System.Windows.Forms.Button AddPowerPoint_Button;
private System.Windows.Forms.Button AddNativeFile_Button;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox groupBox3;
private System.Windows.Forms.Button RefreshContent_Button;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.FolderBrowserDialog DownloadFolderBrowser_FolderBrowser;
private System.Windows.Forms.Button SetBusy_Button;
private System.Windows.Forms.Button Alerts_Button;
}
}
The following example is the interaction code for the previously declared window. The example contains all of the API calls that are needed to manage meeting content.
using System;
using System.Windows.Forms;
using Microsoft.Lync.Model;
using Microsoft.Lync.Model.Group;
using Microsoft.Lync.Model.Conversation;
using Microsoft.Lync.Model.Conversation.Sharing;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.IO;
namespace ContentSharing
{
public partial class ContentSharing_Form : Form
{
#region class field declarations
/// <summary>
/// The Application sharing modality of a remote presenting participant.
/// </summary>
ContentSharingModality _RemoteParticipantSharingModality;
/// <summary>
/// The new shareable content object created by the user.
/// </summary>
ShareableContent _ShareableContent;
/// <summary>
/// The file name and path of the PowerPoint deck to upload.
/// </summary>
string _PowerPointDeckName = string.Empty;
//1.0 - class field declaration
/// <summary>
/// Lync client platform. The entry point to the API
/// </summary>
Microsoft.Lync.Model.LyncClient _LyncClient;
/// <summary>
/// Represents a Lync conversation
/// </summary>
Conversation _conversation;
/// <summary>
/// Dictionary of all contacts selected from the multi-select enabled contact list on
/// UI
/// </summary>
Dictionary<string, Contact> _selectedContacts = new Dictionary<string, Contact>();
/// <summary>
/// The file name and path of a native file to upload.
/// </summary>
string _NativeFileNameAndPath = string.Empty;
/// <summary>
/// The file name of a native file to upload.
/// </summary>
string _NativeFileName = string.Empty;
#endregion
#region video demo methods
/// <summary>
/// Ask user to select a PowerPoint slide deck to be uploaded
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PickAPowerPoint_Button_Click(object sender, EventArgs e)
{
PickContentItemPath_OpenFileDialog.Title = "Choose a PowerPoint deck";
PickContentItemPath_OpenFileDialog.RestoreDirectory = true;
if (PickContentItemPath_OpenFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
_PowerPointDeckName = PickContentItemPath_OpenFileDialog.FileName;
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void AddPowerPoint_Button_Click(object sender, EventArgs e)
{
//15.0 - Create and upload a PowerPoint slide deck.
if (((Modality)_conversation.Modalities[ModalityTypes
.ContentSharing]).State == ModalityState.Disconnected)
{
ConnectCSM();
}
else
{
if (!((Modality)_conversation.Modalities[ModalityTypes.ContentSharing])
.CanInvoke(ModalityAction.CreateShareablePowerPointContent))
{
return;
}
if (_PowerPointDeckName.Length > 0)
{
try
{
ContentSharingModality c = ((ContentSharingModality)_conversation
.Modalities[ModalityTypes.ContentSharing]);
string pptTitle = string.Empty;
Int32 lastWhack = _PowerPointDeckName.LastIndexOf(@"\");
//Strip off PowerPoint deck path, leaving only the file name to
//be assigned as the ShareableContent.Title property
pptTitle = _PowerPointDeckName.Substring(
lastWhack + 1, _PowerPointDeckName.Length - (lastWhack + 1));
c.BeginCreateContentFromFile(
ShareableContentType.PowerPoint,
pptTitle,
_PowerPointDeckName,
false,
CreateShareableContentCallback,
c);
}
catch (InvalidStateException)
{
MessageBox.Show("Invalid state exception on BeginCreateContent ");
}
catch (NotInitializedException)
{
MessageBox.Show("Not initialized exception on BeginCreateContent ");
}
finally
{
//Clear the powerpoint deck name. The name will be filled again by
//the user when they choose another deck to upload.
_PowerPointDeckName = null;
}
}
}
}
/// <summary>
/// Connect the conversation ContentSharingModality the first time the user
/// tries to upload a shareable content item
/// </summary>
private void ConnectCSM()
{
//11.0 - Connect content sharing modality
if (((Modality)_conversation.Modalities[ModalityTypes.ContentSharing])
.CanInvoke(ModalityAction.Connect))
{
try
{
((Modality)_conversation.Modalities[ModalityTypes.ContentSharing]).
BeginConnect((ar) =>
{
((Modality)_conversation.Modalities[ModalityTypes.ContentSharing]).
EndConnect(ar);
}
, null);
}
catch (OperationException oe)
{
Console.WriteLine("Operation exception " + oe.Message);
}
}
}
/// <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)
{
AddAListItemDelegate EventLogger = new AddAListItemDelegate(AddAListItem);
ContentSharingModality csm = ((ContentSharingModality)_conversation
.Modalities[ModalityTypes.ContentSharing]);
EnableDisableButtonDelegate d = new EnableDisableButtonDelegate(EnableDisableButton);
switch (e.Action)
{
case ModalityAction.CreateShareableNativeFileOnlyContent:
//9.0 - create and upload native file content
if (e.IsAvailable == false)
return;
if (_NativeFileName.Length == 0 || _NativeFileNameAndPath.Length == 0)
{
return;
}
UploadAFile();
break;
case ModalityAction.CreateShareablePowerPointContent:
//9.1 - Create shareable powerpoint content
//If the user has chosen a PowerPoint deck to upload, then create
//and upload it when the action is available
if (_PowerPointDeckName.Length > 0)
{
try
{
string pptTitle = string.Empty;
Int32 lastWhack = _PowerPointDeckName.LastIndexOf(@"\");
//Strip off PowerPoint deck path, leaving only the file name to
//be assigned as the ShareableContent.Title property
pptTitle = _PowerPointDeckName.Substring(
lastWhack + 1
, _PowerPointDeckName.Length - (lastWhack + 1));
csm.BeginCreateContentFromFile(
ShareableContentType.PowerPoint,
pptTitle,
_PowerPointDeckName,
false,
(ar) =>
{
try
{
ShareableContent sContent;
sContent = csm.EndCreateContentFromFile(ar);
_PowerPointDeckName = string.Empty;
sContent.Upload();
}
catch (MaxContentsExceededException)
{
MessageBox.Show(
"The meeting content bin is full. PowerPoint deck "
+ "cannot be uploaded");
}
catch (ContentTitleExistException)
{
MessageBox.Show(
"The meeting content bin already contains an item "
+ "with this title. PowerPoint deck cannot be uploaded");
}
catch (ContentTitleInvalidException)
{
MessageBox.Show(
"The whiteboard title is invalid. PowerPoint deck"
+ " cannot be uploaded");
}
}
, null);
}
catch (InvalidStateException) { }
catch (NotInitializedException) { }
finally
{
//Clear the powerpoint deck name. The name will be filled again
//by the user when they choose another deck to upload.
_PowerPointDeckName = null;
}
}
break;
case ModalityAction.CreateShareableWhiteboardContent:
//9.2 - Create whiteboard
if (csm.CanInvoke(
ModalityAction.CreateShareableWhiteboardContent))
{
csm.BeginCreateContent(
ShareableContentType.Whiteboard
, ShareableContentTitle_Textbox.Text,
(ar) =>
{
try
{
ShareableContent sContent = csm.EndCreateContent(ar);
sContent.Upload();
}
catch (MaxContentsExceededException)
{
MessageBox.Show(
"The meeting content bin is full. Whiteboard cannot be "
+ "uploaded");
}
catch (ContentTitleExistException)
{
MessageBox.Show(
"The meeting content bin already contains an item with "
+ "this title. Whiteboard cannot be uploaded");
}
catch (ContentTitleInvalidException)
{
MessageBox.Show(
"The whiteboard title is invalid. Whiteboard cannot "
+ "be uploaded");
}
}
, null);
//Clear the whiteboard title entry field
this.Invoke(
new ChangeControlTextDelegate(ChangeControlText)
, new object[] { ShareableContentTitle_Textbox, "" });
}
break;
case ModalityAction.Accept:
//9.3 - accept sharing invitation
_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;
}
}
/// <summary>
/// Raised when an item is added to the content bin
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void _sharingModality_ContentAdded(object sender, ContentCollectionChangedEventArgs e)
{
//14.9 - Add the new content bin item to the UI list
AddAListItemDelegate ListAdder = new AddAListItemDelegate(AddAListItem);
string newItem = string.Empty;
e.Item.ActionAvailabilityChanged += _ShareableContent_ActionAvailabilityChanged;
newItem = e.Item.Type.ToString() + "-" + e.Item.Title;
this.Invoke(ListAdder, new object[] { Content_Listbox, newItem });
this.Invoke(new EnableDisableButtonDelegate(EnableDisableButton)
, new object[] { ContentShare_Button, true });
}
/// <summary>
/// Places a selected content bin item on the sharing stage for presentation
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ContentShare_Button_Click(object sender, EventArgs e)
{
//14.4 - Present the content on the sharing stage
string selectedItem = (string)Content_Listbox.SelectedItem;
foreach (ShareableContent sContent in ((ContentSharingModality)_conversation
.Modalities[ModalityTypes.ContentSharing]).ContentCollection)
{
if (sContent.Type.ToString() + "-" + sContent.Title == selectedItem)
{
int hrReason;
if (sContent.CanInvoke(ShareableContentAction.Present, out hrReason))
{
_ShareableContent = sContent;
sContent.Present();
}
else
{
MessageBox.Show(
"Cannot present "
+ sContent.Type.ToString()
+ ": "
+ hrReason.ToString());
}
break;
}
}
}
/// <summary>
/// Return to meeting view of presented PowerPoint deck
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SyncWithPresenter_Button_Click(object sender, EventArgs e)
{
//15.1 - Return to meeting view of PowerPoint presentation
try
{
ShareableContent shareableContent = ((ContentSharingModality)_conversation
.Modalities[ModalityTypes.ContentSharing]).ActiveContent;
if (shareableContent.Type == ShareableContentType.PowerPoint)
{
PowerPointContent ppc = shareableContent as PowerPointContent;
int dr;
if (ppc.CanInvoke(ShareableContentAction.SyncWithPresenter, out dr))
{
if (ppc.IsInSyncWithPresenter == false)
{
ppc.SyncWithPresenter();
}
else
{
MessageBox.Show("You're in sync with presenter");
}
}
}
}
catch (InvalidOperationException ioe)
{
Console.WriteLine("Invalid operation " + ioe.Message);
}
catch (COMException c)
{
Console.WriteLine("COMException " + c.Message);
}
catch (Exception ex)
{
Console.WriteLine("Exception " + ex.Message);
}
}
/// <summary>
/// Take over as presenter of the shared content
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TakeOverAsPresenter_Button_Click(object sender, EventArgs e)
{
ShareableContent activeContent = ((ContentSharingModality)_conversation
.Modalities[ModalityTypes.ContentSharing]).ActiveContent;
if (activeContent != null)
{
int dr;
if (activeContent.CanInvoke(ShareableContentAction.TakeOverAsPresenter, out dr))
{
activeContent.TakeOverAsPresenter();
}
}
}
/// <summary>
/// Scroll forward one slide in PowerPoint deck
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void GoForward_Button_Click_1(object sender, EventArgs e)
{
//15.2 - scroll to next slide in PPT deck.
try
{
ShareableContent shareableContent = ((ContentSharingModality)_conversation
.Modalities[ModalityTypes.ContentSharing]).ActiveContent;
if (shareableContent.Type == ShareableContentType.PowerPoint)
{
PowerPointContent ppc = shareableContent as PowerPointContent;
ppc.GoForward();
}
}
catch (InvalidOperationException ioe)
{
Console.WriteLine("Cannot scroll PowerPoint deck forward " + ioe.Message);
}
}
/// <summary>
/// Scroll back one slide in PowerPoint deck
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void GoBack_Button_Click_1(object sender, EventArgs e)
{
//15.3 - Scroll to previous slide in PPT deck.
try
{
ShareableContent shareableContent = ((ContentSharingModality)_conversation
.Modalities[ModalityTypes.ContentSharing]).ActiveContent;
if (shareableContent.Type == ShareableContentType.PowerPoint)
{
PowerPointContent ppc = shareableContent as PowerPointContent;
ppc.GoBackward();
}
}
catch (InvalidOperationException ioe)
{
Console.WriteLine("Cannot scroll PowerPoint deck back " + ioe.Message);
}
}
/// <summary>
/// Removes a presented content item from the sharing stage
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void StopSharingContent_Button_Click(object sender, EventArgs e)
{
//14.5 - Stop sharing content
ContentSharingModality csm = (ContentSharingModality)_conversation
.Modalities[ModalityTypes.ContentSharing];
int hrReason;
if (csm.ActiveContent.CanInvoke(ShareableContentAction.StopPresenting, out hrReason))
{
csm.ActiveContent.StopPresenting();
}
else
{
MessageBox.Show(
"Cannot stop presenting "
+ csm.ActiveContent.Type.ToString()
+ ": " + hrReason.ToString());
}
}
/// <summary>
/// As of Beta 1 refresh, ClearAllAnnotations is not implemented.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ClearAnnotations_Button_Click(object sender, EventArgs e)
{
//14.6 - Clear annotiations from the active content
ContentSharingModality csm =
(ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing];
int hrReason;
if (csm.ActiveContent.CanInvoke(
ShareableContentAction.ClearAllAnnotations, out hrReason))
{
csm.ActiveContent.ClearAllAnnotations();
}
}
/// <summary>
/// Un-registers event handlers for all conversation objects and ends the conversation
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void EndConversation_Button_Click(object sender, EventArgs e)
{
//14.8 - Clean up event registration and end conversation
if (_conversation == null)
{
return;
}
if (_conversation.State != ConversationState.Terminated)
{
//Clean up all conversation object registration so that events do not fire
//on conversation objects as they are being nulled by the platform when the
//conversation terminates.
ContentSharingModality contentModality = (ContentSharingModality)_conversation
.Modalities[ModalityTypes.ContentSharing];
_conversation.ParticipantAdded -= _conversation_ParticipantAdded;
_conversation.ParticipantRemoved -= _conversation_ParticipantRemoved;
contentModality.ModalityStateChanged -= Modality_ModalityStateChanged;
contentModality.ActionAvailabilityChanged -= _sharingModality_ActionAvailabilityChanged;
contentModality.ActiveContentChanged -= _sharingModality_ActiveContentChanged;
contentModality.ContentAdded -= _sharingModality_ContentAdded;
contentModality.ContentRemoved -= _sharingModality_ContentRemoved;
foreach (Participant p in _conversation.Participants)
{
((Modality)p.Modalities[ModalityTypes.ContentSharing])
.ActionAvailabilityChanged -= _sharingModality_ActionAvailabilityChanged;
}
_conversation.End();
}
}
/// <summary>
/// User selects a content bin item. Check for the availability of an action
/// on the selected content.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Content_Listbox_SelectedIndexChanged(object sender, EventArgs e)
{
ListBox list = (ListBox)sender;
ContentShare_Button.Enabled = false;
string selectedItem = (string)list.SelectedItem;
foreach (ShareableContent sContent in ((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).ContentCollection)
{
if (sContent.Type.ToString() + "-" + sContent.Title == selectedItem)
{
int hrReason;
switch (sContent.Type)
{
case ShareableContentType.NativeFile:
if (sContent.CanInvoke(ShareableContentAction.DownloadFile, out hrReason))
{
DownloadAttachment_Button.Enabled = true;
}
break;
case ShareableContentType.PowerPoint:
if (sContent.CanInvoke(ShareableContentAction.DownloadFile, out hrReason))
{
DownloadAttachment_Button.Enabled = true;
}
ContentShare_Button.Enabled = false;
if (sContent.CanInvoke(ShareableContentAction.Present, out hrReason))
{
ContentShare_Button.Enabled = true;
}
StopSharingContent_Button.Enabled = false;
if (sContent.CanInvoke(ShareableContentAction.StopPresenting, out hrReason))
{
StopSharingContent_Button.Enabled = true;
}
break;
case ShareableContentType.Whiteboard:
ContentShare_Button.Enabled = false;
if (sContent.CanInvoke(ShareableContentAction.Present, out hrReason))
{
ContentShare_Button.Enabled = true;
}
StopSharingContent_Button.Enabled = false;
if (sContent.CanInvoke(ShareableContentAction.StopPresenting, out hrReason))
{
StopSharingContent_Button.Enabled = true;
}
break;
}
break;
}
}
}
#endregion
#region UI event handlers
/// <summary>
/// Creates and uploads a whiteboard session
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ShareNewContent_Button_Click(object sender, EventArgs e)
{
//14.3 - Create new whiteboard and upload it to content bin.
ContentSharingModality csm = (ContentSharingModality)_conversation
.Modalities[ModalityTypes.ContentSharing];
if (csm.State == ModalityState.Disconnected)
{
ConnectCSM();
}
else
{
if (csm.CanInvoke(ModalityAction.CreateShareableWhiteboardContent))
{
csm.BeginCreateContent(
ShareableContentType.Whiteboard
, ShareableContentTitle_Textbox.Text
, (ar) =>
{
try
{
ShareableContent sContent = csm.EndCreateContent(ar);
sContent.Upload();
}
catch (MaxContentsExceededException)
{
MessageBox.Show(
"The meeting content bin is full. Whiteboard "
+ "cannot be uploaded");
}
catch (ContentTitleExistException)
{
MessageBox.Show(
"The meeting content bin already contains an item "
+ "with this title. Whiteboard cannot be uploaded");
}
catch (ContentTitleInvalidException)
{
MessageBox.Show(
"The whiteboard title is invalid. Whiteboard cannot "
+ "be uploaded");
}
}
, null);
//Clear the whiteboard title string entry field
ShareableContentTitle_Textbox.Text = string.Empty;
}
}
}
/// <summary>
/// If content stage item is a Whiteboard, saves whiteboard annotations.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SaveAnnotations_Button_Click(object sender, EventArgs e)
{
//14.7 - Save the annotations on the active content
ContentSharingModality csm = (ContentSharingModality)_conversation
.Modalities[ModalityTypes.ContentSharing];
int hrReason;
if (csm.ActiveContent.CanInvoke(ShareableContentAction.SaveAnnotation, out hrReason))
{
DirectoryInfo dirInfo = new DirectoryInfo(@"c:\users\public\");
if (dirInfo.Exists)
{
csm.ActiveContent.SaveAnnotation(
@"c:\users\public\"
+ csm.ActiveContent.Title
+ ".png"
, ContentSavingFileType.PNG);
//Get a FileInfo object that wraps the downloaded file
FileInfo file = new FileInfo(
@"c:\users\public\"
+ csm.ActiveContent.Title
+ ".png");
//If the file was downloaded then give the user the download path
//and file name
if (file.Exists)
{
MessageBox.Show(
"Annotations have been saved at "
+ file.Directory.FullName + @"\"
+ csm.ActiveContent.Title + ".png");
}
}
}
else
{
MessageBox.Show("Annotations cannot be saved for " + _ShareableContent.Title);
}
}
/// <summary>
/// Accepts an invitation to share meeting content
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Accept_Button_Click(object sender, EventArgs e)
{
if (_RemoteParticipantSharingModality.CanInvoke(ModalityAction.Accept))
{
_RemoteParticipantSharingModality.Accept();
}
}
/// <summary>
/// invoked when sample form is loaded. Initializes fields, gets API entry point,
/// registers for events on Lync Client and ConversationManager.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ContentSharing_Form_Load(object sender, EventArgs e)
{
try
{
//2.0 - Get client platform
//Get the API entry point
_LyncClient = LyncClient.GetClient();
//2.1 - Check for UI suppression
//Resource sharing is not supported in UI suppression mode. Sample closes
//if Lync UI is suppressed
if (_LyncClient.InSuppressedMode == true)
{
MessageBox.Show(
"Lync Client is in UI Suppressed mode. Sharing is not supported.",
"Application Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
this.Close();
}
_LyncClient.Self.Contact.ContactInformationChanged += new EventHandler<ContactInformationChangedEventArgs>(Contact_ContactInformationChanged);
//Display the current state of the Lync client.
ClientStateString_Label.Text = _LyncClient.State.ToString();
//2.2 - sign in
//If the Lync client is signed out, sign into the Lync client
if (_LyncClient.State == ClientState.SignedOut)
{
_LyncClient.EndSignIn(_LyncClient.BeginSignIn(
"terrya@contoso.com",
"terrya@contoso.com",
"MyPassword",
null,
null));
}
//Display the current state of the Lync client.
ClientStateString_Label.Text = _LyncClient.State.ToString();
//2.3 - event registration
//Register for the three Lync client events needed so that application is
//notified when:
// * Lync client signs in or out
// * A new conversation is added (remotely via invite or locally by user)
// * A conversation is removed (conversation ends)
_LyncClient.StateChanged += _LyncClient_StateChanged;
_LyncClient.ConversationManager.ConversationAdded +=
ConversationManager_ConversationAdded;
_LyncClient.ConversationManager.ConversationRemoved +=
ConversationManager_ConversationRemoved;
//Enable the start conversation button on the UI
Start_Button.Enabled = true;
//ShareDesktop.LoadAllContacts loads the contact list on the UI with
//all contacts that are in the user's Lync client contact list.
LoadAllContacts();
}
catch (NotInitializedException)
{
MessageBox.Show(
"Client is not initialized. Closing form",
"Lync Client Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
this.Close();
}
catch (ClientNotFoundException)
{
MessageBox.Show(
"Client is not running. Closing form",
"Lync Client Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
this.Close();
}
catch (Exception exc)
{
MessageBox.Show(
"General exception: " + exc.Message,
"Lync Client Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
this.Close();
}
}
void Contact_ContactInformationChanged(object sender, ContactInformationChangedEventArgs e)
{
// MessageBox.Show("Contact information changed " + e.ChangedContactInformation.ToString());
}
/// <summary>
/// Starts a new conversation
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Start_Button_Click(object sender, EventArgs e)
{
//4.0 - Create new Conversation object for new meeting
if (_conversation == null)
{
Contact aContact;
foreach (Object selectedObject in Contact_ListBox.SelectedItems)
{
aContact = _LyncClient.ContactManager.GetContactByUri(
selectedObject.ToString());
if (!_selectedContacts.ContainsKey(selectedObject.ToString()))
{
_selectedContacts.Add(selectedObject.ToString(), aContact);
}
}
_conversation = _LyncClient.ConversationManager.AddConversation();
}
}
/// <summary>
/// Downloads an attachment or powerpoint from meeting
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DownloadAttachment_Button_Click(object sender, EventArgs e)
{
//get title of selected content to be downloaded
string selectedItem = (string)Content_Listbox.SelectedItem;
//14.0 - get download target folder
//get path to download
string downloadPath = string.Empty;
DownloadFolderBrowser_FolderBrowser.Description =
"Pick a meeting content download folder";
if (DownloadFolderBrowser_FolderBrowser.ShowDialog() ==
System.Windows.Forms.DialogResult.OK)
{
downloadPath = DownloadFolderBrowser_FolderBrowser.SelectedPath;
}
//14.1 - Get shareable content out of meeting content bin to download
//Get each native file attachment and then download it
ShareableContent contentToDownload = null;
foreach (ShareableContent sContent in ((ContentSharingModality)_conversation.
Modalities[ModalityTypes.ContentSharing]).ContentCollection)
{
if (sContent.Type + "-" + sContent.Title == selectedItem)
{
contentToDownload = sContent;
break;
}
}
//14.2 - download the file
if (contentToDownload != null)
{
//14.2 - download content
string downloadFileTitle = string.Empty;
if (contentToDownload.Title.Length != 0)
{
downloadFileTitle = contentToDownload.Title;
}
else
{
downloadFileTitle = contentToDownload.Properties[ShareableContentProperty.
Title].ToString();
}
int hr;
if (contentToDownload.CanInvoke(ShareableContentAction.DownloadFile, out hr))
{
contentToDownload.BeginDownloadFile(
downloadPath + @"\" + downloadFileTitle, (ar) =>
{
MessageBox.Show("Downloaded file: " +
contentToDownload.EndDownloadFile(ar));
}
, null);
}
}
}
private void PickNativeFile_Button_Click(object sender, EventArgs e)
{
PickContentItemPath_OpenFileDialog.RestoreDirectory = true;
PickContentItemPath_OpenFileDialog.Title = "Choose a native file";
PickContentItemPath_OpenFileDialog.FileName = "*.*";
if (PickContentItemPath_OpenFileDialog.ShowDialog() == System.Windows.Forms.
DialogResult.OK)
{
_NativeFileNameAndPath = PickContentItemPath_OpenFileDialog.FileName;
_NativeFileName = PickContentItemPath_OpenFileDialog.SafeFileName;
}
}
private void UploadNativeFile_Button_Click(object sender, EventArgs e)
{
//10.0 - upload native file
if (_NativeFileName.Length == 0 || _NativeFileNameAndPath.Length == 0)
{
return;
}
if (((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).
State == ModalityState.Connected)
{
UploadAFile();
}
else
{
ConnectCSM();
}
}
private void Reject_Button_Click(object sender, EventArgs e)
{
if (_RemoteParticipantSharingModality.CanInvoke(ModalityAction.Reject))
{
_RemoteParticipantSharingModality.Reject(ModalityDisconnectReason.Decline);
}
}
private void ContentSharing_Form_FormClosing(object sender, FormClosingEventArgs e)
{
if (_conversation == null)
{
return;
}
if (_conversation.State != ConversationState.Terminated)
{
_conversation.End();
}
}
#endregion
#region Client event handlers
/// <summary>
/// Handles the event raised when a user signs in to or out of the Lync client.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void _LyncClient_StateChanged(object sender, ClientStateChangedEventArgs e)
{
//If the client has signed in then get the client's contact list and enable the conversation start button.
if (e.NewState == ClientState.SignedIn)
{
this.Invoke(new LoadAllContactsDelegate(LoadAllContacts));
this.Invoke(new EnableDisableButtonDelegate(EnableDisableButton), new object[] { Start_Button, true });
}
else
{
this.Invoke(new ClearAllContactsDelegate(ClearAllContacts));
this.Invoke(new EnableDisableButtonDelegate(EnableDisableButton), new object[] { Start_Button, false });
this.Invoke(new ChangeLabelTextDelegate(ChangeLabelText), new object[] { ClientStateString_Label, e.NewState.ToString() });
this.Invoke(new EnableDisableButtonDelegate(EnableDisableButton), new object[] { EndConversation_Button, false });
}
}
#endregion
#region conversation manager event handlers
/// <summary>
/// Handles the event raised when a new conversation is added. This sample only hosts
/// one conversation at a time. Once this event is handled, the sample un-registers
/// for this event. The event is registered again when this conversation is removed
/// from the ContactManager.Conversations collection upon termination of this
/// conversation.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ConversationManager_ConversationAdded(
object sender, Microsoft.Lync.Model.Conversation.ConversationManagerEventArgs e)
{
//5.0 - filter shadow conversations
if (IsShadowConversation(e.Conversation))
{
return;
}
//5.1 - Is this our conversation?
if (e.Conversation != _conversation)
{
return;
}
//5.2 - conversation and conversation modality registration
//Register for participant added events on the new conversation
_conversation.ParticipantAdded += _conversation_ParticipantAdded;
_conversation.ParticipantRemoved += _conversation_ParticipantRemoved;
_conversation.StateChanged += new EventHandler<ConversationStateChangedEventArgs>(_conversation_StateChanged);
((Modality)_conversation.Modalities[ModalityTypes.ContentSharing]).ModalityStateChanged
+= Modality_ModalityStateChanged;
((Modality)_conversation.Modalities[ModalityTypes.ContentSharing]).ActionAvailabilityChanged
+= _sharingModality_ActionAvailabilityChanged;
((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).
ActiveContentChanged += _sharingModality_ActiveContentChanged;
((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).
ContentAdded += _sharingModality_ContentAdded;
((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).
ContentRemoved += _sharingModality_ContentRemoved;
//5.3 - add selected contacts to the meeting
//Iterate on the contact dictionary that is filled from the contact Sip addresses
//selected from the contact list UI control. Add each selected contact to the
//conversation, causing an invitation to be sent to each contact.
if (_conversation.CanInvoke(ConversationAction.AddParticipant))
{
foreach (Contact selectedContact in _selectedContacts.Values)
{
Participant newParticipant = _conversation.AddParticipant(selectedContact);
}
}
//5.4 - send first IM message that initiates meeting invitation
((InstantMessageModality)_conversation.Modalities[ModalityTypes.InstantMessage]).
BeginSendMessage(
"Hello. I would like to share something with you.",
(ar) =>
{
try
{
((InstantMessageModality)_conversation.Modalities[ModalityTypes.InstantMessage]).EndSendMessage(ar);
}
catch (LyncClientException) { Console.WriteLine("Message could not be delivered"); }
}
, null);
}
void _conversation_StateChanged(object sender, ConversationStateChangedEventArgs e)
{
if (e.NewState == ConversationState.Active)
{
this.Invoke(new EnableDisableButtonDelegate(EnableDisableButton), new object[] { EndConversation_Button, true });
this.Invoke(new EnableDisableButtonDelegate(EnableDisableButton), new object[] { Start_Button, false });
}
if (e.NewState == ConversationState.Terminated)
{
this.Invoke(new EnableDisableButtonDelegate(EnableDisableButton), new object[] { EndConversation_Button, false });
this.Invoke(new EnableDisableButtonDelegate(EnableDisableButton), new object[] { Start_Button, true });
}
}
/// <summary>
/// Handles the event raised when the active conversation is terminated and removed from the collection of conversations
/// on ConversationManager.Conversations
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ConversationManager_ConversationRemoved(object sender, ConversationManagerEventArgs e)
{
if (e.Conversation == _conversation)
{
this.Invoke(new SetContactSelectionModeDelegate(SetContactSelectionMode), new object[] { SelectionMode.MultiSimple });
this.Invoke(new EnableDisableButtonDelegate(EnableDisableButton), new object[] { EndConversation_Button, false });
this.Invoke(new EnableDisableButtonDelegate(EnableDisableButton), new object[] { Start_Button, true });
this.Invoke(new ChangeLabelTextDelegate(ChangeLabelText), new object[] { ContactList_Label, "People in Meeting" });
this.Invoke(new LoadAllContactsDelegate(LoadAllContacts));
this.Invoke(new ClearAllListItemsDelegate(ClearAllListItems), new object[] { Content_Listbox });
this.Invoke(new ChangeControlBackgroundDelegate(ChangeControlBackground), new object[] { ModalityConnectedState_Panel, System.Drawing.Color.Red });
//Un-register for participant events on the conversation that is terminated.
_conversation.ParticipantAdded -= _conversation_ParticipantAdded;
_conversation.ParticipantRemoved -= _conversation_ParticipantRemoved;
_ShareableContent = null;
//de-reference the class state
_conversation = null;
//Clear out the contact list on the UI to be replaced with only the contacts selected for the current conversation.
this.Invoke(new LoadAllContactsDelegate(LoadAllContacts));
}
}
#endregion
#region Conversation event handlers
/// <summary>
/// Handles the participant added event. Registers for events on the application
/// sharing modality for the
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void _conversation_ParticipantAdded(
object sender, ParticipantCollectionChangedEventArgs e)
{
//7.0 - participant event registration: IM modality and content sharing modality
//Register for event raised when a participant IMModality is connected to
//the conversation.
//Use this event to add participant to contact listbox
((Modality)e.Participant.Modalities[ModalityTypes.InstantMessage]).
ModalityStateChanged += Participant_ModalityStateChanged;
//Is this added participant the local user?
if (!e.Participant.IsSelf)
{
//Event raised when content sharing action availability changes for a
//participant
((Modality)e.Participant.Modalities[ModalityTypes.ContentSharing]).
ActionAvailabilityChanged += _sharingModality_ActionAvailabilityChanged;
}
}
/// <summary>
/// Handles the event raised when a particpant is removed from the conversation.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void _conversation_ParticipantRemoved(object sender, ParticipantCollectionChangedEventArgs e)
{
this.Invoke(new RemoveAContactDelegate(RemoveAContact), new object[] { e.Participant.Contact.Uri});
}
#endregion
#region participant event handlers
/// <summary>
/// Raised when the state of a participant's IM modality changes
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Participant_ModalityStateChanged(Object sender, ModalityStateChangedEventArgs e)
{
//8.0 Add participant URI to meeting participant list on UI
//Modality will be connected for each particpant whethere they have accepted the
//shariing invite or not.
if (sender.GetType().Name == "InstantMessageModality")
{
if (e.NewState == ModalityState.Connected)
{
InstantMessageModality IMModality = sender as InstantMessageModality;
this.Invoke(
new AddAContactDelegate(AddAContact),
new object[] { IMModality.Participant.Contact.Uri });
}
}
}
#endregion
#region application sharing modality event handlers
/// <summary>
/// Handles the even raised when the state of an application sharing modality changes.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Modality_ModalityStateChanged(object sender, ModalityStateChangedEventArgs e)
{
//12.0 - show changes in conversation content sharing modality state
//Modality will be connected for each particpant whethere they have accepted
//the shariing invite or not.
switch (sender.GetType().Name)
{
case "ContentSharingModality":
ContentSharingModality thisModality = sender as ContentSharingModality;
if (thisModality == ((ContentSharingModality)_conversation.
Modalities[ModalityTypes.ContentSharing]))
{
switch (e.NewState)
{
case ModalityState.Connecting:
this.Invoke(
new ChangeControlBackgroundDelegate(
ChangeControlBackground),
new object[] { ModalityConnectedState_Panel,
System.Drawing.Color.Gold });
break;
case ModalityState.Connected:
this.Invoke(
new ChangeControlBackgroundDelegate(
ChangeControlBackground),
new object[] { ModalityConnectedState_Panel,
System.Drawing.Color.Green });
this.Invoke(
new EnableDisableButtonDelegate(EnableDisableButton),
new object[] { ShareWhiteboard_Button, true });
break;
case ModalityState.Disconnected:
this.Invoke(
new ChangeControlBackgroundDelegate(
ChangeControlBackground),
new object[] {
ModalityConnectedState_Panel,
System.Drawing.Color.Red });
break;
}
}
break;
}
}
/// <summary>
/// Raised when an item is removed from the content bin
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void _sharingModality_ContentRemoved(object sender, ContentCollectionChangedEventArgs e)
{
this.Invoke(new ClearAllListItemsDelegate(ClearAllListItems), new object[] { Content_Listbox});
foreach (ShareableContent sc in ((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).ContentCollection)
{
string newItem = sc.Type.ToString() + "-" + sc.Title;
this.Invoke(new AddAListItemDelegate(AddAListItem), new object[] { Content_Listbox, newItem });
}
}
/// <summary>
/// Raised when one content bin item is moved off the sharing stage and is replaced by another
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void _sharingModality_ActiveContentChanged(object sender, ActiveContentChangedEventArgs e)
{
if (e.ActiveContent != null)
{
_ShareableContent = e.ActiveContent;
this.Invoke(new ChangeLabelTextDelegate(ChangeLabelText), new object[] { ActiveContent_Label, e.ActiveContent.Title });
EnableDisableButtonDelegate d = new EnableDisableButtonDelegate(EnableDisableButton);
if (e.ActiveContent.Type == ShareableContentType.PowerPoint)
{
this.Invoke(d, new object[] { GoBack_Button, true });
this.Invoke(d, new object[] { GoForward_Button, true });
this.Invoke(d, new object[] { ClearAnnotations_Button, false });
Int32 hrReason;
if (e.ActiveContent.CanInvoke(ShareableContentAction.ClearAllAnnotations, out hrReason))
{
this.Invoke(d, new object[] { ClearAnnotations_Button, true });
}
}
else if (e.ActiveContent.Type == ShareableContentType.Whiteboard)
{
Int32 hrReason;
if (e.ActiveContent.CanInvoke(ShareableContentAction.ClearAllAnnotations, out hrReason))
{
this.Invoke(d, new object[] { ClearAnnotations_Button, true });
}
if (e.ActiveContent.CanInvoke(ShareableContentAction.SaveAnnotation, out hrReason))
{
this.Invoke(d, new object[] { SaveAnnotations_Button, true });
}
this.Invoke(d, new object[] { GoBack_Button, false });
this.Invoke(d, new object[] { GoForward_Button, false });
}
}
}
#endregion
#region Shareable Content Event Callback Methods
/// <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)
{
ShareableContent sContent = (ShareableContent)sender;
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;
case ShareableContentAction.Present:
if (sContent.Owner != _LyncClient.Self.Contact)
{
this.Invoke(d, new object[] { SyncWithPresenter_Button, !e.IsAvailable });
}
break;
}
}
#endregion
#region API Operation callback methods
private void CreateShareableContentCallback(System.IAsyncResult ar)
{
try
{
ContentSharingModality shareModality = (ContentSharingModality)ar.AsyncState;
ShareableContent sContent;
if (_PowerPointDeckName == string.Empty && _NativeFileNameAndPath == string.Empty)
{
sContent = shareModality.EndCreateContent(ar);
}
else
{
sContent = shareModality.EndCreateContentFromFile(ar);
_PowerPointDeckName = string.Empty;
_NativeFileNameAndPath = string.Empty;
}
sContent.Upload();
}
catch (MaxContentsExceededException) {
}
catch (ContentTitleExistException) {
}
catch (ContentTitleInvalidException) {
}
}
#endregion
#region UI update helper methods and their delegates
private delegate void LoadAllContactsDelegate();
/// <summary>
/// Iterates on all groups and adds an Uri string for each contact in a group to a
/// list on the UI
/// </summary>
private void LoadAllContacts()
{
//3.0 - Get all Contact objects from contact list
//Set the selection mode of the UI list to multi-select
Contact_ListBox.SelectionMode = SelectionMode.MultiSimple;
Contact_ListBox.Items.Clear();
foreach (Group group in _LyncClient.ContactManager.Groups)
{
foreach (Contact contact in group)
{
if (!Contact_ListBox.Items.Contains(contact.Uri))
Contact_ListBox.Items.Add(contact.Uri);
}
}
}
/// <summary>
/// Filters out the "shadow" conversation that is created when a content sharing
/// modality is connected in a conversation when the user has Tabbed Conversations
/// enabled in the Lync UI
/// </summary>
/// <param name="newConversation"></param>
/// <returns></returns>
private Boolean IsShadowConversation(Conversation newConversation)
{
//6.0 - detecting a shadow conversation
if (newConversation.SelfParticipant != null)
{
return false;
}
foreach (Modality m in newConversation.Modalities.Values)
{
if (m.State == ModalityState.Notified)
{
return false;
}
}
return true;
}
/// <summary>
/// Creates a ShareableObject for selected native file and uploads the file
/// </summary>
private void UploadAFile()
{
//13.0 - upload a native file
try
{
if (((ContentSharingModality)_conversation.
Modalities[ModalityTypes.ContentSharing]).
CanInvoke(ModalityAction.CreateShareableNativeFileOnlyContent))
{
ContentSharingModality contentSharingModality =
(ContentSharingModality)_conversation.
Modalities[ModalityTypes.ContentSharing];
contentSharingModality.BeginCreateContentFromFile(
ShareableContentType.NativeFile,
_NativeFileName,
_NativeFileNameAndPath,
true,
(ar) =>
{
ShareableContent sContent = contentSharingModality.
EndCreateContentFromFile(ar);
_PowerPointDeckName = string.Empty;
_NativeFileNameAndPath = string.Empty;
sContent.Upload();
}
, null);
}
}
catch (InvalidStateException)
{
MessageBox.Show(
"Invalid state exception on BeginCreateContent ");
}
catch (NotInitializedException)
{
MessageBox.Show(
"Not initialized exception on BeginCreateContent ");
}
finally { _NativeFileNameAndPath = string.Empty; }
}
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;
}
private delegate void ClearAllListItemsDelegate(ListBox boxToClear);
private void ClearAllListItems(ListBox boxToClear)
{
boxToClear.Items.Clear();
}
private delegate void AddAListItemDelegate(ListBox listToAppend, object itemToAdd);
private void AddAListItem(ListBox listToAppend, object itemToAdd)
{
if (!listToAppend.Items.Contains(itemToAdd))
{
listToAppend.Items.Add(itemToAdd);
}
}
private delegate void RemoveListItemDelegate(ListBox listToTruncate, string itemToRemove);
private void RemoveListItem(ListBox listToTruncate, string itemToRemove)
{
if (listToTruncate.Items.Contains(itemToRemove))
{
listToTruncate.Items.Remove(itemToRemove);
}
}
private delegate void ClearAllContactsDelegate();
private void ClearAllContacts()
{
Contact_ListBox.Items.Clear();
}
private delegate void AddAContactDelegate(string ContactUri);
private void AddAContact(string ContactUri)
{
Contact_ListBox.SelectionMode = SelectionMode.One;
if (!Contact_ListBox.Items.Contains(ContactUri))
{
Contact_ListBox.Items.Add(ContactUri);
}
}
private delegate void RemoveAContactDelegate(string ContactUri);
private void RemoveAContact(string ContactUri)
{
Contact_ListBox.Items.Remove(ContactUri);
}
private delegate void ChangeButtonTextDelegate(Button buttonToChange, string newText);
private void ChangeButtonText(Button buttonToChange, string newText)
{
buttonToChange.Text = newText;
}
private delegate void SetContactSelectionModeDelegate(SelectionMode newMode);
/// <summary>
/// Changes the contact list on the UI from single-select to multi-select mode
/// </summary>
/// <param name="newMode"></param>
private void SetContactSelectionMode(SelectionMode newMode)
{
Contact_ListBox.SelectionMode = newMode;
}
private delegate void ChangeLabelTextDelegate(Label labelToUpdate, string newText);
/// <summary>
/// Replaces the text of any label control on the UI with new text
/// </summary>
/// <param name="labelToUpdate"></param>
/// <param name="newText"></param>
private void ChangeLabelText(Label labelToUpdate, string newText)
{
labelToUpdate.Text = newText;
}
private delegate void ChangeControlTextDelegate(object controlToUpdate, string newText);
/// <summary>
/// Replaces the text property value with a new string
/// </summary>
/// <param name="controlToUpdate"></param>
/// <param name="newText"></param>
private void ChangeControlText(object controlToUpdate, string newText)
{
switch (controlToUpdate.GetType().Name)
{
case "TextBox":
TextBox updatedTextBox = controlToUpdate as TextBox;
updatedTextBox.Text = newText;
break;
case "Button":
Button updatedButton = controlToUpdate as Button;
updatedButton.Text = newText;
break;
case "Label":
Label updatedLabel = controlToUpdate as Label;
updatedLabel.Text = newText;
break;
}
}
private delegate void ChangeControlBackgroundDelegate(Control controlToChange, System.Drawing.Color newColor);
private void ChangeControlBackground(Control controlToChange, System.Drawing.Color newColor)
{
controlToChange.BackColor = newColor;
}
#endregion
#region constructors
public ContentSharing_Form()
{
InitializeComponent();
}
public ContentSharing_Form(Conversation newConversation)
{
InitializeComponent();
_conversation = newConversation;
}
#endregion
private void RemoveFromBin_Button_Click(object sender, EventArgs e)
{
string selectedItem = (string)Content_Listbox.SelectedItem;
foreach (ShareableContent sContent in ((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).ContentCollection)
{
if (sContent.Type.ToString() + "-" + sContent.Title == selectedItem)
{
int hrReason;
if (sContent.CanInvoke(ShareableContentAction.Remove, out hrReason))
{
_ShareableContent = sContent;
sContent.ActionAvailabilityChanged -= _ShareableContent_ActionAvailabilityChanged;
sContent.Remove();
}
else
{
MessageBox.Show("Cannot remove " + selectedItem.ToString() +": " + hrReason.ToString());
}
break;
}
}
}
private void RefreshContent_Button_Click(object sender, EventArgs e)
{
Content_Listbox.Items.Clear();
foreach (ShareableContent sc in ((ContentSharingModality)_conversation.Modalities[ModalityTypes.ContentSharing]).ContentCollection)
{
string newItem = string.Empty;
newItem = sc.Type.ToString() + "-" + sc.Title;
Content_Listbox.Items.Add(newItem);
}
}
private void SetBusy_Button_Click(object sender, EventArgs e)
{
Dictionary<PublishableContactInformationType, object> publishableAvailablility = new Dictionary<PublishableContactInformationType, object>();
ContactAvailability currentAvailability = (ContactAvailability) _LyncClient.Self.Contact.GetContactInformation(ContactInformationType.Availability);
if (currentAvailability != ContactAvailability.DoNotDisturb)
{
publishableAvailablility.Add(PublishableContactInformationType.Availability, ContactAvailability.DoNotDisturb);
}
else
{
publishableAvailablility.Add(PublishableContactInformationType.Availability, ContactAvailability.Free);
}
_LyncClient.Self.BeginPublishContactInformation(
publishableAvailablility,
(ar) =>
{
try
{
_LyncClient.Self.EndPublishContactInformation(ar);
}
catch (LyncClientException lce)
{
MessageBox.Show("Exception on publish availablility " + lce.Message);
}
}
,null);
SetBusy_Button.Text = "Clear meeting status";
}
private void Alerts_Button_Click(object sender, EventArgs e)
{
Alerts alertsForm = new Alerts();
alertsForm.ShowDialog();
}
}
}