Recently I had the pleasure to develop an Eventsink for Exchange 2003. But since the client didn't want to install the .NET framework on their Exchange servers, I had a change to practice my C++.
One of the things I had to check if the number of attendees had changed between creating the appointment and saving the changes. The obvious way to access this property on the IAppointment interface. Opening an appointment should be simple when you have access to the record:
// pEventInfo is a parameter for the OnSyncSave method
IExStoreDispEventInfoPtr pDispEventInfo = (IExStoreDispEventInfoPtr)pEventInfo;
// get the record
_RecordPtr rec;
pDispEventInfo->get_EventRecord( (IDispatch**)&rec );
// load the appointment from the record
IAppointmentPtr iAppointment(__uuid(Appointment));
iAppointment->DataSource->OpenObject(rec, "_Record");
Unfortunately this always fails for an appointment, with an invalid parameter exception (it does work for an IMessage). Luckily the IDataSource interface also has an Open method, which accepts a Stream:
// pEventInfo is a parameter for the OnSyncSave method
IExStoreDispEventInfoPtr pDispEventInfo = (IExStoreDispEventInfoPtr)pEventInfo;
// get the record
_RecordPtr rec;
pDispEventInfo->get_EventRecord( (IDispatch**)&rec );
// open a stream
_StreamPtr iStream(__uuidof(Stream));
iStream->Open(_variant_t((IDispatch*)rec,/* fCopy */true), adModeReadWrite, adOpenStreamFromRecord, BSTR(""), BSTR(""));
// load the appointment from the stream
IAppointmentPtr iAppointment(__uuidof(Appointment));
iAppointment->DataSource->OpenObject(iStream, "_Stream");
// close the stream
iStream->Close();