Outlook Items

Every individual contact, appointment, and task stored within Pocket Outlook is considered its own object. Each has its own unique identifier, as well as a set of properties and methods that are appropriate for the object type.

All of the item interfaces (IContact, ITask, and IAppointment) expose the methods described in Table 10.10, which are used for adding, deleting, and modifying the object.

Table 10.10. Base Methods for the Outlook Item Interfaces

Method

Description

Copy()

Copies the object

Delete()

Deletes the object

Display()

Displays the object

Save()

Saves the object

Using the base methods of an object is fairly straightforward. For example, let's look at what is involved in using the IContact::Display() method to show a contact:

// Get an item
IContact *pNewContact = NULL;
hr = pIContactItems->Add((IDispatch **)&pNewContact);
if(FAILED(hr))
   return FALSE;

// Configure the contact
pNewContact->put_FirstName(TEXT("Randy"));
pNewContact->put_LastName(TEXT("Rants"));
pNewContact->put_WebPage(TEXT("http://www.randyrants.com"));

// Save it, then display it
hr = pNewContact->Save();
hr = pNewContact->Display();

Figure 10.3 illustrates the contact that is shown when calling the IContact::Display() method.

Figure 10.3. The IContact::Display() method in action

graphics/10fig03.gif

The IContact Interface

The IContact interface is used to represent an individual contact entry in the Contacts folder. The interface implements the common Outlook item methods?Save(), Delete(), Copy(), and Display()?and supports the properties described in Table 10.11.

Table 10.11. IContact Properties

Property

Get/Put

Description

Anniversary

Get/put

Gets or sets the anniversary date

Application

Get

Returns a pointer to the IPOutlookApp interface

AssistantName

Get/put

Gets or sets the name of the contact's assistant

AssistantTelephoneNumber

Get/put

Gets or sets the telephone number of the contact's assistant

Birthday

Get/put

Gets or sets the birthday

Body

Get/put

Gets or sets any notes for the contact (up to 60KB)

BodyInk

Get/put

Gets or sets an InkNote BLOB (Binary Large Object) for the contact. Both the IContact::Body and IContact::BodyInk properties access the same note; however, IContact::Body returns only the text, whereas IContact::BodyInk returns the entire ink object.

Business2TelephoneNumber

Get/put

Gets or sets the second business telephone number

BusinessAddressCity

Get/put

Gets or sets the business city

BusinessAddressCountry

Get/put

Gets or sets the business country

BusinessAddressPostalCode

Get/put

Gets or sets the business zip code

BusinessAddressState

Get/put

Gets or sets the business state

BusinessAddressStreet

Get/put

Gets or sets the business street

BusinessFaxNumber

Get/put

Gets or sets the business fax number

BusinessTelephoneNumber

Get/put

Gets or sets the business telephone number

CarTelephoneNumber

Get/put

Gets or sets the car phone number

Categories

Get/put

Gets or sets the categories for the contact (up to 1,023 characters)

Children

Get/put

Gets or sets the number of children

CompanyName

Get/put

Gets or sets the company name

Department

Get/put

Gets or sets the department

Email1Address

Get/put

Gets or sets the first e-mail address

Email2Address

Get/put

Gets or sets the second e-mail address

Email3Address

Get/put

Gets or sets the third e-mail address

FileAs

Get/put

Gets or sets the filing string for the contact

FirstName

Get/put

Gets or sets the first name

Home2TelephoneNumber

Get/put

Gets or sets the second home telephone number

HomeAddressCity

Get/put

Gets or sets the home city

HomeAddressCountry

Get/put

Gets or sets the home country

HomeAddressPostalCode

Get/put

Gets or sets the home zip code

HomeAddressState

Get/put

Gets or sets the home state

HomeAddressStreet

Get/put

Gets or sets the home street address

HomeFaxNumber

Get/put

Gets or sets the home fax number

HomeTelephoneNumber

Get/put

Gets or sets the home telephone number

JobTitle

Get/put

Gets or sets the contact's job title

LastName

Get/put

Gets or sets the last name

MiddleName

Get/put

Gets or sets the middle name

MobileTelephoneNumber

Get/put

Gets or sets the mobile phone number

OfficeLocation

Get/put

Gets or sets the office location for the contact

Oid

Get

Gets the object identifier

OtherAddressCity

Get/put

Gets or sets the other address city

OtherAddressCountry

Get/put

Gets or sets the other address country

OtherAddressPostalCode

Get/put

Gets or sets the other address zip code

OtherAddressState

Get/put

Gets or sets the other address state

OtherAddressStreet

Get/put

Gets or sets the other address street

PagerNumber

Get/put

Gets or sets the pager number

RadioTelephoneNumber

Get/put

Gets or sets the radio telephone number

Spouse

Get/put

Gets or sets the spouse's name

Suffix

Get/put

Gets or sets the suffix for the contact's name

Title

Get/put

Gets or sets the contact's title

WebPage

Get/put

Gets or sets the Web page for the contact

YomiCompanyName

Get/put

Gets or sets the Japanese phonetic rendering of the contact's company name

YomiFirstName

Get/put

Gets or sets the Japanese phonetic rendering of the contact's first name

YomiLastName

Get/put

Gets or sets the Japanese phonetic rendering of the contact's last name

To add a new contact to Pocket Outlook's database, you can create a new IContact item by using the IPOutlookItemCollection interface to get a pointer and add it to the Contacts folder. Once you have modified the properties for the contact, use the IContact::Save() method to save it to the object store.

In addition to storing the basic properties for a contact, Pocket Outlook also supports the capability to store an InkNote with each item (see Figure 10.4). An InkNote is a Binary Large Object (BLOB) that contains data. They are drawn on the screen (attached to the item), and are used with the Rich Ink control.

Figure 10.4. An InkNote attached to a contact

graphics/10fig04.gif

To work with an InkNote that is attached to an Outlook contact (or any other Outlook item), you can use the Body and BodyInk parameters. The Body parameter is used to extract a text string from the hand-drawn note.

The IAppointment Interface

The IAppointment interface is used to represent an object in the Calendar folder, and can specify an appointment, meeting, or recurring event (such as a weekly meeting). In addition to the common Outlook item methods?Save(), Delete(), Copy(), and Display()?the IAppointment interface also supports the methods described in Table 10.12.

Table 10.12. IAppointment Methods

Method

Description

Cancel()

Sends a cancellation request for the appointment

ClearRecurrencePattern()

Clears the recurrence pattern for the appointment

GetRecurrencePattern()

Gets the IRecurrencePattern interface for the appointment

Send()

Sends the appointment (meeting request) to all recipients

The IAppointment interface supports the properties described in Table 10.13.

You can create, modify, and delete Pocket Outlook appointments just as you would any other Pocket Outlook object. After getting a pointer to the IPOutlookItemCollection interface for the Calendar database, you can perform any action you want on it.

Table 10.13. IAppointment Properties

Property

Get/Put

Description

AllDayEvent

Get/put

Indicates whether the appointment is an all-day appointment

Application

Get

Returns a pointer to the IPOutlookApp interface

Body

Get/put

Gets or sets the note attached to the appointment (up to 20KB)

BodyInk

Get/put

Gets or sets an InkNote BLOB for the appointment. Both the IAppointment::Body and IAppointment::BodyInk properties access the same note; however, IAppointment::Body returns only the text, whereas IAppointment::BodyInk returns the entire ink object.

BusyStatus

Get/put

Gets or sets the status when a meeting is occurring; options include Busy, Free, Out of Office, or Tentative

Categories

Get/put

Gets or sets the categories assigned

Duration

Get/put

Gets or sets the length of the appointment, in minutes

End

Get/put

Gets or sets the end date and time of the appointment. This must be later than or equal to the start time.

isRecurring

Get

Indicates whether the appointment is recurring

Location

Get/put

Gets or sets the location

MeetingStatus

Get

Indicates whether the appointment is a meeting request or not. An appointment is considered a meeting if it has recipients.

Oid

Get

Gets the object identifier

Recipients

Get

Gets the IRecipients interface for the appointment

ReminderMinutesBeforeStart

Get/put

Gets or sets the number of minutes before the start of the appointment that the reminder should be launched

ReminderOptions

Get/put

Gets or sets the reminder options for the appointment

ReminderSet

Get/put

Indicates whether the user should be reminded of the appointment

ReminderSoundFile

Get/put

Gets or sets the path and filename of the sound file to be used for the reminder. The IAppointment::ReminderSet property should be set to TRUE, and the IAppointment::Reminder Options should have the olSound option turned on.

Sensitivity

Get/put

Indicates the sensitivity of the appointment: normal or private

Start

Get/put

Gets or sets the start date and time of the appointment. This must be earlier or equal to the end time.

Subject

Get/put

Gets or sets the subject of the appointment (up to 4,096 characters)

For example, if you wanted to add a new appointment, you could do the following:

// Calendar folder
IFolder *pIFolder = NULL;
hr = pOlApp->GetDefaultFolder(olFolderCalendar, &pIFolder);
if(FAILED(hr)) {
   OutputDebugString(TEXT("Could not get the calendar
       folder"));
   return FALSE;
}

// Get the collection
IPOutlookItemCollection *pIAppItems = NULL;
hr = pIFolder->get_Items(&pIAppItems);
if(FAILED(hr)) {
   pIFolder->Release();
   return FALSE;
}

// Add a new appointment
IAppointment *pIAppoint = NULL;
hr = pIAppItems->Add((IDispatch **)&pIAppoint);
if(FAILED(hr)) {
   pIAppItems->Release();
   pIFolder->Release();
   return FALSE;
}

// Set up my appointment details
SYSTEMTIME sysTime;
DATE dtAppoint;

memset(&sysTime, 0, sizeof(SYSTEMTIME));
sysTime.wMonth = 8;
sysTime.wDay = 30;
sysTime.wYear = 2003;

SystemTimeToVariantTime(&sysTime, &dtAppoint);

pIAppoint->put_Subject(TEXT("Mike's Birthday"));
pIAppoint->put_Start(dtAppoint);
pIAppoint->put_AllDayEvent(VARIANT_TRUE);

// Save it
pIAppoint->Save();

// Clean up
if(pIAppoint)
   pIAppoint->Release();
if(pIAppItems)
   pIAppItems->Release();
if(pIFolder)
   pIFolder->Release();

Two additional interfaces can be used in conjunction with the IAppointment interface to provide more robust appointments:

  1. The IRecurrencePattern interface is used to set up appointments and meetings that occur on more than one occasion.

  2. The IRecipients interface is used to change an appointment into a meeting request.

The methods IAppointment::ClearRecurrencePattern() and IAppointment::GetRecurrencePattern() are used with the IRecurrencePattern interface, and are covered later in this chapter (both the ITask and IAppointment interfaces can support recurrence patterns).

When you create a new appointment, you generally need to include other individuals besides yourself. This is where the IRecipients interface is used; it changes an appointment into what is called a meeting request. The methods IAppointment::Cancel() and IAppointment::Send() are used for canceling and sending these types of requests to other people.

To get the pointer to the IRecipients interface that will be used for an appointment, you can use the IAppointment::get_Recipients() property, which is defined as follows:

HRESULT IAppointment::get_Recipients(IRecipients **pRecipients);

This property returns a pointer to an IRecipient interface that you can use to add, modify, or delete people from the recipients list.

Appointment Recipients

The IRecipients interface is a collection of recipients for an appointment. The interface supports the methods described in Table 10.14.

Table 10.14. IRecipients Methods

Method

Description

Add()

Adds a recipient to the meeting request

Item()

Gets the IRecipient interface for the specified item

Remove()

Removes a recipient

The IRecipients interface also supports the properties described in Table 10.15.

Table 10.15. IRecipients Properties

Property

Get/Put

Description

Application

Get

Returns a pointer to the IPOutlookApp interface

Count

Get

Gets the number of recipients in the list

Each individual recipient in the collection is represented by an IRecipient interface, which supports the properties described in Table 10.16.

Table 10.16. IRecipient Properties

Property

Get/Put

Description

Address

Get/put

Gets or sets the e-mail address of the recipient. This property cannot be set to NULL.

Application

Get

Returns a pointer to the IPOutlookApp interface

Name

Get

Gets the display name of the recipient

To either add or delete individuals from a meeting request, you first must get the appointment's specific IRecipients interface by calling the IAppointment::get_Recipients() property. For example, if you wanted to add a few individuals to a meeting request, you could do the following:

// Get the collection
IPOutlookItemCollection *pIAppItems = NULL;
hr = pIFolder->get_Items(&pIAppItems);
if(FAILED(hr)) {
   pIFolder->Release();
   return FALSE;
}

// Get an appointment
IAppointment *pIAppoint = NULL;
hr = pIAppItems->Item(1, (IDispatch **)&pIAppoint);
if(FAILED(hr)) {
   pIAppItems->Release();
   pIFolder->Release();
   return FALSE;
}

// Get the recipient list
IRecipients *pIRecip = NULL;
hr = pIAppoint->get_Recipients(&pIRecip);
if(FAILED(hr)) {
   pIAppoint->Release();
   pIAppItems->Release();
   pIFolder->Release();
   return FALSE;
}

// Add recipients
IRecipient *pINewRecipient = NULL, *pINewRecipient2 = NULL;
pIRecip->Add(TEXT("Barry"), &pINewRecipient);
pIRecip->Add(TEXT("Jennifer"), &pINewRecipient2);

// Remember to save appointment
pIAppoint->Save();
Verifying a Recipient

After you have used the IRecipients::Add() method to add new people to a recipient list for an appointment (or you have modified the list), it is a good practice to verify that the names you have added are actually valid. This task is simplified by using the IPOlRecipient interface. The interface has a single method, described in Table 10.17.

Table 10.17. IPOlRecipient Method

Method

Description

Resolve()

Resolves the name of a recipient with the Contacts database

To get a valid pointer for the IPOlRecipient interface, you need to call the QueryInterface() function on the IRecipient object that you want to validate:

// Resolve
IPOlRecipient *pResolvRecip = NULL;
hr = pINewRecipient->QueryInterface(IID_IPOlRecipient,
   (LPVOID *)&pResolvRecip);

After you have the pointer to the interface, you can call the IPOlRecipient::Resolve() method. This will validate the name of the IRecipient object by searching the Contacts database for a matching first and last name. The method has the following prototype:

HRESULT IPOlRecipient::Resolve(VARIANT_BOOL fShowDialog,
   VARIANT_BOOL *pfResolved);

The first parameter, fShowDialog, should be set to TRUE if you want the method to display a dialog box that lists all of the matching e-mail addresses. If it is set to FALSE, then the function will fail if more than one contact matches. The pfResolved parameter will return TRUE or FALSE, depending on whether the function has successfully resolved an address or not.

The ITask Interface

The ITask interface is used to represent an individual task that is located in the Tasks folder. In addition to the common Outlook item methods?Save(), Delete(), Copy(), and Display()?the ITask interface also supports the methods described in Table 10.18.

The ITask interface supports the properties described in Table 10.19.

Table 10.18. ITask Methods

Method

Description

ClearRecurrencePattern()

Clears the recurrence pattern for the task

GetRecurrencePattern()

Gets the IRecurrencePattern interface for the task

SkipRecurrence()

Moves the recurrence pattern forward one recurrence

Table 10.19. ITask Properties

Property

Get/Put

Description

Application

Get

Returns a pointer to the IPOutlookApp interface

Body

Get/put

Gets or sets the note attached to the task (up to 60KB)

BodyInk

Get/put

Gets or sets an InkNote BLOB for the task. Both the ITask::Body and ITask::BodyInk properties access the same note; however, ITask::Body returns only the text, whereas ITask::BodyInk returns the entire ink object.

Categories

Get/put

Gets or sets the categories for the task

Complete

Get/put

Indicates whether the task has been completed

DateCompleted

Get

Gets the date and time when the task was completed, depending on whether the ITask::Complete property is set to TRUE

DueDate

Get/put

Gets or sets the date the task is due

Importance

Get/put

Gets or sets the importance level of the task (Low, Normal, or High)

IsRecurring

Get

Indicates whether the task is recurring

Oid

Get

Gets the object identifier

ReminderOptions

Get/put

Gets or sets the reminder options for the task

ReminderSet

Get/put

Indicates whether the user should be reminded of the task

ReminderSoundFile

Get/put

Gets or sets the path and filename of the sound file to be used for the reminder. The ITask::ReminderSet property should be set to TRUE, and the ITask::ReminderOptions should have the olSound option turned on.

ReminderTime

Get/put

Gets or sets when the reminder will occur

Sensitivity

Get/put

Gets or sets the sensitivity of the task to either Normal or Private

StartDate

Get/put

Gets or sets the start date for the task

Subject

Get/put

Gets or sets the subject for the task (up to 4,095 characters)

TeamTask

Get/put

Indicates whether the task is a team task or not

Using Recurrence Patterns in Appointments and Tasks

Both the IAppointment and ITask interfaces enable you to set up a recurrence pattern for a particular Outlook item by using the IRecurrencePattern interface. The interface supports the method described in Table 10.20.

Table 10.20. IRecurrencePattern Method

Method

Description

GetOccurrence()

Gets a specific IAppointment interface occurring on the specified date and at the specified time

The IRecurrencePattern interface supports the properties described in Table 10.21.

Table 10.21. IRecurrencePattern Properties

Property

Get/Put

Type

Valid For

Description

Application

Get

All

Both

Returns a pointer to the IPOutlookApp interface

DayOfMonth

Get/put

Monthly, Yearly

Both

Gets or sets the days in a month on which the recurrence occurs (from 1 to 31)

DayOfWeekMask

Get/put

MonthNth, Weekly, YearNth

Both

Gets or sets the days of the week on which the recurrence occurs (from olSunday through olSaturday)

Duration

Get/put

All

IAppointment

Gets or sets the duration of the recurring task or appointment. This value is ignored if both IRecurrencePattern::StartTime and IRecurrencePattern::EndTime are set.

EndTime

Get/put

All

IAppointment

Gets or sets the time when a recurring task or appointment ends

Exceptions

Get

All

IAppointment

Gets the list of appointments that cause an exception to the recurrence pattern. Returns a pointer to the IException interface.

Instance

Get/put

MonthNth, YearNth

Both

Gets or sets the week of the month on which the recurrence occurs (from 1 to 5)

Interval

Get/put

Daily, Monthly, MonthNth, Weekly

Both

Gets or sets the number of units between occurrences (from 1 to 999)

MonthOfYear

Get/put

Yearly, YearNth

Both

Gets or sets the month in which a recurrence occurs (from 1 to 12)

NoEndDate

Get/put

All

Both

Indicates whether the pattern has an end date

Occurrences

Get/put

All

Both

Gets or sets the number of occurrences

PatternEndDate

Get/put

All

Both

Gets or sets the end date of the recurrence. You must set IRecurrencePattern::NoEndDate to TRUE.

PatternStartDate

Get/put

All

Both

Gets or sets the start date of the recurrence

RecurrenceType

Get/put

All

Both

Gets or sets the recurrence type (Daily, Weekly, Monthly, Every Nth Month, Yearly, or Every Nth Years)

StartTime

Get/put

All

IAppointment

Gets or sets the start time for recurring tasks or appointments

To create a new recurring appointment or task, you first need to get the IRecurrencePattern interface for the IAppointment or ITask object by calling the ::GetRecurrencePattern() method on the object.

You should initially configure how often the recurrence will occur by using the IRecurrencePattern::RecurrenceType() property. A recurrence pattern's frequency can be set with one of the following values:

  • Use the olRecursDaily constant to have the task or appointment repeat every day.

  • Use the olRecursWeekly constant to have the task or appointment repeat every week.

  • Use the olRecursMonthly constant to have the task or appointment repeat every month.

  • Use the olRecursMonthNth constant to have the task or appointment repeat every Nth month.

  • Use the olRecursYearly constant to have the task or appointment repeat every year.

  • Use the olRecursYearNth constant to have the task or appointment repeat every Nth year.

Once you have set the IRecurrencePattern::RecurrenceType() property, you can proceed to configure the start time and date for the pattern.

The following example creates a new task that has a recurrence pattern:

// Create a new task
IFolder *pIFolder = NULL;
hr = pOlApp->GetDefaultFolder(olFolderTasks, &pIFolder);
if(FAILED(hr)) {
   OutputDebugString(TEXT("Could not get the tasks
      folder"));
   return FALSE;
}

// Get the collection
IPOutlookItemCollection *pITaskItems = NULL;
hr = pIFolder->get_Items(&pITaskItems);
if(FAILED(hr)) {
   pIFolder->Release();
   return FALSE;
}

// Create a new task
ITask *pITask = NULL;
hr = pITaskItems->Add((IDispatch **)&pITask);
if(FAILED(hr)) {
   pITaskItems->Release();
   pIFolder->Release();
   return FALSE;
}

// Add some info
pITask->put_Subject(TEXT("Check morning news"));

// Get the recurrence pattern
IRecurrencePattern *pIRecur = NULL;
hr = pITask->GetRecurrencePattern(&pIRecur);
if(FAILED(hr)) {
   pITask->Release();
   pITaskItems->Release();
   pIFolder->Release();
   return FALSE;
}

// Set it to fire daily starting tommorow
SYSTEMTIME sysTime;
DATE dtAppoint;

GetSystemTime(&sysTime);
sysTime.wDay++;
SystemTimeToVariantTime(&sysTime, &dtAppoint);

pIRecur->put_RecurrenceType(olRecursDaily);
pIRecur->put_NoEndDate(VARIANT_TRUE);
pIRecur->put_StartTime(dtAppoint);

// Save it
pITask->Save();

// Clean up
pIRecur->Release();
pITask->Release();
pITaskItems->Release();
pIFolder->Release();
Recurrence Exceptions

Whenever an appointment that already has a recurrence pattern assigned to it is modified, Pocket Outlook will automatically create an exception for it. To get a list of exceptions for a recurring appointment, you can use the IRecurrencePattern::get_Exceptions() property, as shown in the following example:

IExceptions *pIExcepts = NULL;
hr = pIRecur->get_Exceptions(&pIExcepts);
if(FAILED(hr)) {
   pIRecur->Release();
   pITask->Release();
   pITaskItems->Release();
   pIFolder->Release();
   return FALSE;
}

// Do something with the exceptions...

The IExceptions interface that is returned is a read-only collection of exceptions for the appointment. The interface supports the single method shown in Table 10.22.

Table 10.22. IExceptions Method

Method

Description

Item()

Gets a specific IException item

The IExceptions interface supports the properties described in Table 10.23.

Table 10.23. IExceptions Properties

Property

Get/Put

Description

Application

Get

Returns a pointer to the IPOutlookApp interface

Count

Get

Gets the number of IException items from the collection

To retrieve a specific exception, you should use the IExceptions::Item() method, which is defined as follows:

HRESULT IExceptions::Item(int iIndex,
  IException **ppExcept);

The first parameter is the index for the exception you are interested in, and is followed by a pointer to a value that will be filled in with the pointer to the specific IException interface.

The IException interface supports the properties described in Table 10.24.

Table 10.24. IException Properties

Property

Get/Put

Description

Application

Get

Returns a pointer to the IPOutlookApp interface

AppointmentItem

Get

Gets the IAppointment interface for the item causing the exception

Deleted

Get

Returns TRUE if the exception is caused because the appointment is being deleted

OriginalDate

Get

Gets the date on which the exception originally occurred