The custom client list in this example is built from a snapshot of the local client contact list persisted by the Office Communicator server. Any changes to the permanent contact list on the server are communicated to your custom contact list using event notification. Typically, these notifications are received due to action on the part of another Office Communicator client. For example, a remote user represented by one of the contacts in your list goes offline. That client notifies the Office Communicator server of its status. In turn, the Office Communicator server notifies your local client of the status change using the DMessengerEvents::OnContactStatusChange event.

When you make a request to add a client to your contact list, you are actually asking the Office Communicator server to add a contact to the persistent store on the server. If you make the request and immediately ask for a new snapshot of your contact list, you might not see your new contact. The Office Communicator server might not have completed your original request to add the contact at the time you make your new snapshot request. To avoid a blocking problem, the example code changes the background color of the custom contact list items for which action is pending rather than displaying a progress dialog. For example, if you select a contact, right-click the contact name, and select Remove Contact. The code sets the background color of the contact item to gray until the OnContactListRemove event handler causes the rebuilding of the contact list.

The DMessengerEvents::OnContactListAdd and DMessengerEvents::OnContactListRemove events serve to notify the local client that an add or remove contact request has completed on the Office Communicator server. The event handlers you register in your application for these events should be responsible for asking for a new snapshot of the contact list. For a complete list of contact list related events, see DMessengerEvents.

For more information about adding or removing a contact from a contact list, see Managing Contacts.

The Office Communicator UI shows Office Communicator users with which a local client has previously interacted. They are listed in a group called "Recent Contacts". These are Office Communicator users with which the local client user has interacted within a defined time period. These users are stored in the local machine registry under HKEY_CURRENT_USER/Software/Microsoft/Communicator/<current user signinname>/GroupStateCacheU/~~. If you want to implement a "Recent Contacts" group in your custom contact list, you should read the values under this key. These registry values are maintained by Office Communicator. You can retrieve a user from the Office Communicator server by passing one of these SigninName values to IMessenger::GetContact. A good way to use this feature is to present the user with this list when he wants to restore a previously deleted contact. It is beyond the scope of this example application to demonstrate this method.

The following code snippet is from the ContactList.cs example source file.

Copy Code
//create new ListViewItem with contact Friendly Name
ListViewItem contactItem = new ListViewItem(

//set tooltip by querying presence properties array for Presence Note
IMessengerContactAdvanced a_contact = (IMessengerContactAdvanced)thisContact;
object[] a_presenceProp = (object[])a_contact.PresenceProperties;
string toolString = a_presenceProp[(int)PRESENCE_PROPERTY.PRESENCE_PROP_PRESENCE_NOTE].ToString();
if (toolString.Length == 0)
   toolString = a_contact.SigninName;
contactItem.ToolTipText = toolString;

//set presence icon and availability string for contact in listview
string statusString = "";
statusString = updateContactList(

//add listview sub item for status column of contact list
ListViewItem.ListViewSubItem itemToAdd = new ListViewItem.ListViewSubItem();
itemToAdd.Name = "Status";
itemToAdd.Text = statusString;

//add sub-item to item

// add item to contact list

Removing a contact from the custom contact list is done as in the following example.

Copy Code
   foreach (ListViewItem selectedContactItem in contactListView.SelectedItems)
	object contactToRemove = null;
	contactToRemove = communicator.GetContact(
									 listDict[selectedContactItem.Index + 1],
	if (contactToRemove != null)
	selectedContactItem.BackColor = Color.Gray;
catch (ArgumentException AE)
			"Contact List Argument Exception: " + 
catch (COMException CE)
			"Contact List COM Exception: " + 
catch (Exception Ex)
			 "Contact List Exception: " + 

See Also