/// <summary> /// Retrieves the modality (audio + video): AvModality.BeginRetrieve() /// </summary> private void buttonRetrieve_Click(object sender, EventArgs e) { //retrieves a call from hold (applies for both audio and video) //the video state will be remembered from before the call was held AsyncCallback callback = new AsyncOperationHandler(avModality.EndRetrieve).Callback; try { avModality.BeginRetrieve(callback, null); } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } }
/// <summary> /// Disconnects the modality: AvModality.BeginDisconnect() /// </summary> private void buttonDisconnectAudio_Click(object sender, EventArgs e) { //ends an audio call or conference by connecting the AvModality try { AsyncCallback callback = new AsyncOperationHandler(avModality.EndDisconnect).Callback; avModality.BeginDisconnect(ModalityDisconnectReason.None, callback, null); } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } }
/// <summary> /// Rejects an incoming call: AvModality.Reject() /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void buttonReject_Click(object sender, EventArgs e) { //rejects an incoming invite (which will disconnect the call) //the ModalityDisconnectReason may be used to specify a reason to the caller side //the reason may be shown on the Lync client conversation window try { avModality.Reject(ModalityDisconnectReason.None); } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } }
/// <summary> /// Forwards the call to a contact or phone number. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void buttonForward_Click(object sender, EventArgs e) { //since forwarding needs a contact, will show a dialog to get user input SelectContactDialog contactDialog = new SelectContactDialog(client.ContactManager); contactDialog.ShowDialog(); //if a contact is selected if (contactDialog.DialogResult == DialogResult.OK && contactDialog.Contact != null) { //transfers the call (both audio and video) to the specified contact AsyncCallback callback = new AsyncOperationHandler(avModality.EndForward).Callback; try { avModality.BeginForward(contactDialog.Contact, callback, null); } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } } }
/// <summary> /// Adds a participant to the conversation. /// </summary> private void buttonAddRosterContact_Click(object sender, EventArgs e) { //obtains the contact SelectContactDialog contactDialog = new SelectContactDialog(client.ContactManager); contactDialog.ShowDialog(this); //if a contact is selected if (contactDialog.DialogResult == DialogResult.OK && contactDialog.Contact != null) { //add a participant to the conversation try { conversation.AddParticipant(contactDialog.Contact); } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } } }
/// <summary> /// Called when a button is pressed in the dial pad dialog. /// /// Sends the DTMF tone using AudioChannel.BeginSendDtmf() /// </summary> void dialpad_DialPadPressed(string tone) { //sends a set of characters (in this case one) as a dial tone try { AsyncCallback callback = new AsyncOperationHandler(audioChannel.EndSendDtmf).Callback; audioChannel.BeginSendDtmf(tone, callback, null); } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } }
//***************************************************************************************** // VideoChannel related actions // // The video channel action will behave differently depending on whether the audio is already // connected. // // If audio is not connected, starting video is equivalent to connecting the modality. If the // conversation already has audio, starting video will start the outgoing video stream. The // other participants in the conversation also need to start their own video. // // Stopping the video channel will stop both outgoing and incoming video. It will remove video // from the conversation. // //***************************************************************************************** /// <summary> /// Starts the video channel: VideoChannel.BeginStart() /// </summary> private void buttonStartVideo_Click(object sender, EventArgs e) { //starts a video call or the video stream in a audio call AsyncCallback callback = new AsyncOperationHandler(videoChannel.EndStart).Callback; try { videoChannel.BeginStart(callback, null); } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } }
/// <summary> /// Accepts an incoming call: AvModality.Accept() /// </summary> private void buttonAccept_Click(object sender, EventArgs e) { //accepts an incoming invite (syncronous operation) try { avModality.Accept(); } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } }
/// <summary> /// Holds the modality (audio + video): AvModality.BeginHold() /// </summary> private void buttonHold_Click(object sender, EventArgs e) { //puts the call on hold (applies for both audio and video) AsyncCallback callback = new AsyncOperationHandler(avModality.EndHold).Callback; try { avModality.BeginHold(callback, null); } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } }
/// <summary> /// Obtains a contact using the URI provided. /// </summary> private void buttonSelect_Click(object sender, EventArgs e) { //gets the typed uri string uri = textBoxAddress.Text; //simple validation: ignores empty string if (string.IsNullOrEmpty(uri)) { Console.WriteLine("No URI specified"); return; } //***************************************************************************************** // contactManager.GetContactByUri // // This method will may return a contact, even if it doesn't match a phone number or a // SIP URI in the database. // // Calls placed using contact object that does not match a valid number or an actual contact // will fail after the modality starts connecting. // //***************************************************************************************** Contact contact = null; //Finds the contact using the provided URI (synchronously) try { contact = lyncContactManager.GetContactByUri(uri); } catch (LyncClientException lyncClientException) { Console.WriteLine("Contact not found. Did you use the sip: or tel: prefix? " + lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } //if there was somebody listening to the event ContactSelected onContactSelected = ContactSelected; if (contact != null && onContactSelected != null) { //notify that the contact was selected onContactSelected(this, contact); } }
/// <summary> /// Transfers the call to a contact: AvModality.BeginTransfer() /// </summary> private void buttonTransfer_Click(object sender, EventArgs e) { //since transfering needs a contact, will show a dialog to get user input SelectContactDialog contactDialog = new SelectContactDialog(client.ContactManager); contactDialog.ShowDialog(); //if a contact is selected if (contactDialog.DialogResult == DialogResult.OK) { //***************************************************************************************** // The argument TransferOptions dictates whether the transfer target is able to redirect the // call or not. If the option is TransferOptions.DisallowRedirection and the target does not // accept the call, it will return to this endpoint. //***************************************************************************************** // Declare a simple handler for the async callback before invoking Transfer... AsyncCallback transferCallback = ar => { try { ModalityState state; IList <string> properties; avModality.EndTransfer(out state, out properties, ar); Console.Out.WriteLine("Transfer state: " + state); } catch (Exception ex) { Console.Out.WriteLine(ex); } }; //transfers the call (both audio and video) to the specified contact try { avModality.BeginTransfer(contactDialog.Contact, TransferOptions.None, transferCallback, null); } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } } }
/// <summary> /// Transfers the call to another conversation: /// </summary> private void buttonConsultTransfer_Click(object sender, EventArgs e) { IList <Conversation> allConversations = client.ConversationManager.Conversations; Debug.Assert(allConversations != null && conversation != null); //obtain the conversation ConversationPickerDialog conversationPickerDialog = new ConversationPickerDialog(); conversationPickerDialog.ShowConversations(allConversations, conversation); conversationPickerDialog.ShowDialog(this); //if a conversation was selected if (conversationPickerDialog.DialogResult == DialogResult.OK && conversationPickerDialog.Conversation != null) { AsyncCallback transferCallback = ar => { try { ModalityState state; IList <string> properties; avModality.EndConsultativeTransfer(out state, out properties, ar); Console.Out.WriteLine("Consultative Transfer state: " + state); } catch (Exception ex) { Console.Out.WriteLine(ex); } }; //does a consultative transfer to the selected conversation //only the TransferOptions.None is allowed here try { avModality.BeginConsultativeTransfer(conversationPickerDialog.Conversation, TransferOptions.None, transferCallback, null); } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } } }
/// <summary> /// Called when a set of contacts are selected from the contact list. /// </summary> void contactFinderControl_ContactSelected(object source, Contact contact) { //creates a new conversation Conversation conversation = null; try { conversation = client.ConversationManager.AddConversation(); } catch (LyncClientException e) { Console.WriteLine(e); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } //Adds a participant to the conversation //the window created for this conversation will handle the ParticipantAdded events if (contact != null && conversation != null) { try { conversation.AddParticipant(contact); } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } } }
//***************************************************************************************** // Conversation Related Actions //***************************************************************************************** /// <summary> /// Changes the ConversationProperty.AutoTerminateOnIdle based on the checkBox state. /// </summary> private void checkBoxAutoTerminateOnIdle_CheckStateChanged(object sender, EventArgs e) { //reads the value of the property bool autoTerminateOnIdle = checkBoxAutoTerminateOnIdle.Checked; //***************************************************************************************** // ConversationProperty.AutoTerminateOnIdle // // By default this property will be set to false, which will cause the conversation to be // terminated when all modalities are disconnected (after at least one has been active). // // When the Lync client is running, there's no need to set this property since the Lync // user interface will set it to true. // // If this application is running in UISuppressionMode, it needs to set this property to // allow the conversation to live after all modalities are disconnected. // //***************************************************************************************** //setting the property for Lync terminate the conversation once it's disconnected try { conversation.BeginSetProperty(ConversationProperty.AutoTerminateOnIdle, autoTerminateOnIdle, null, null); } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } }
/// <summary> /// Returns the display name of the contact. /// </summary> public override string ToString() { StringBuilder participantNames = new StringBuilder(100); //iterates through the participants in the conversation to list their display names foreach (Participant participant in Conversation.Participants) { //ignores the self participant if (participant.IsSelf) { continue; } //concatenates the display name into the list string name = null; try { name = participant.Contact.GetContactInformation(ContactInformationType.DisplayName) as string; } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } participantNames.Append(name ?? "<Unknown>").Append(", "); } return(participantNames.ToString()); }
/// <summary> /// Ends the conversation if the user closes the window. /// </summary> private void ConversationWindow_FormClosing(object sender, FormClosingEventArgs e) { //need to remove event listeners otherwide events may be received after the form has been unloaded conversation.StateChanged -= conversation_StateChanged; conversation.ParticipantAdded -= conversation_ParticipantAdded; conversation.ParticipantRemoved -= conversation_ParticipantRemoved; conversation.ActionAvailabilityChanged -= conversation_ActionAvailabilityChanged; avModality.ActionAvailabilityChanged -= avModality_ActionAvailabilityChanged; avModality.ModalityStateChanged -= avModality_ModalityStateChanged; audioChannel.ActionAvailabilityChanged -= audioChannel_ActionAvailabilityChanged; audioChannel.StateChanged -= audioChannel_StateChanged; videoChannel.ActionAvailabilityChanged -= videoChannel_ActionAvailabilityChanged; videoChannel.StateChanged -= videoChannel_StateChanged; //if the conversation is active, will end it if (conversation.State != ConversationState.Terminated) { //ends the conversation which will disconnect all modalities try { conversation.End(); } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } } }
/// <summary> /// Returns the display name of the contact. /// </summary> public override string ToString() { //in case ToString() is called before the participant is set if (Participant == null) { return(string.Empty); } //obtains the display name of the participant string displayName = null; try { displayName = Participant.Contact.GetContactInformation(ContactInformationType.DisplayName) as string; } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } //if the contact is self, then add a (self) sufix displayName = displayName ?? "<Unknown>"; return(Participant.IsSelf ? displayName + " (self)" : displayName); }
/// <summary> /// Removes a participant from the conversation. /// </summary> private void buttonRemoveRosterContact_Click(object sender, EventArgs e) { //validates if there's a participant selected if (listBoxRosterContacts.SelectedIndex <= 0) { MessageBox.Show("Please select a participant (other than self)."); return; } //get the selected participant for removal ParticipantItem item = listBoxRosterContacts.SelectedItem as ParticipantItem; //removes the participant from the conversation try { if (item != null) { conversation.RemoveParticipant(item.Participant); } } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } }
/// <summary> /// Shows the contact item control. /// </summary> private void ShowContactSelectionControl() { //removes the sign in control / pending sign-in/out message tableLayoutPanel.Controls.Remove(signInControl); tableLayoutPanel.Controls.Remove(labelPendingSignInOut); //adds the contact selection control to the second row of the panel tableLayoutPanel.Controls.Add(contactFinderControl, 0, 1); //show the self contact name string name = null; try { name = client.Self.Contact.GetContactInformation(ContactInformationType.DisplayName) as string; } catch (LyncClientException e) { Console.WriteLine(e); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } // value can be null if presence document item is not available. labelUserName.Text = name ?? "<Unknown>"; }
/// <summary> /// Signs-In on Lync. /// </summary> private void buttonSignIn_Click(object sender, EventArgs e) { try { client.BeginSignIn(textBoxSignInAddress.Text, textBoxUser.Text, textBoxPassword.Text, HandleEndSignIn, null); } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } }
/// <summary> /// Updates the initial UI state and registers for client events. /// </summary> private void MainWindow_Load(object sender, EventArgs e) { //shows the current client state toolStripStatusLabel.Text = client.State.ToString(); // register for state updates. Whenever the client change its state, this // event will be fired. For example, during Sign-In it will likely move from: // SignedOut -> SigningIn -> SignedIn client.StateChanged += client_StateChanged; // register for the client exiting event // when/if the Lync process exits, it will fire this event client.ClientDisconnected += client_ClientDisconnected; //*********************************************************************************** // This application works with UISuppressionMode = true or false // // UISuppressionMode hides the Lync user interface. // // Registry key for enabling UISuppressionMode: // // 32bit OS: // [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\15.0\Lync] // "UISuppressionMode"=dword:00000001 // // 64bit OS: // [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Communicator] // "UISuppressionMode"=dword:00000001 // // When running with UISuppressionMode = 1 and this application is the only one // using the client, it's necessary to Initialize the client. The following check // verifies if the client has already been initialized. If it hasn't, the code will // call BeginInitialize() proving a callback method, on which this application's // main UI will be presented (either Sign-In or contact input, if already signed in). //*********************************************************************************** //if this client is in UISuppressionMode... if (client.InSuppressedMode && client.State == ClientState.Uninitialized) { //...need to initialize it try { client.BeginInitialize(this.ClientInitialized, null); } catch (LyncClientException lyncClientException) { Console.WriteLine(lyncClientException); } catch (SystemException systemException) { if (LyncModelExceptionHelper.IsLyncException(systemException)) { // Log the exception thrown by the Lync Model API. Console.WriteLine("Error: " + systemException); } else { // Rethrow the SystemException which did not come from the Lync Model API. throw; } } } else //not in UI Suppression, so the client was already initialized { //registers for conversation related events //these events will occur when new conversations are created (incoming/outgoing) and removed client.ConversationManager.ConversationAdded += ConversationManager_ConversationAdded; client.ConversationManager.ConversationRemoved += ConversationManager_ConversationRemoved; //show sign-in or contact selection ShowMainContent(); } }