Criar um item de compromisso complexo de recorrência
Aplica-se a: Outlook 2013 | Outlook 2016
MAPI pode ser usado para criar itens de compromisso recorrentes.
Para obter informações sobre como baixar, exibir e executar o código do aplicativo MFCMAPI e do projeto CreateOutlookItemsAddin referenciado neste tópico, consulte Instalar os exemplos usados nesta seção.
Para criar um item de compromisso
Abra um repositório de mensagens. Para obter informações sobre como abrir um repositório de mensagens, consulte Abrir um Repositório de Mensagens.
Abra uma pasta Calendário no repositório de mensagens. Consulte PR_IPM_APPOINTMENT_ENTRYID (PidTagIpmAppointmentEntryId).
Chame o método IMAPIFolder::CreateMessage na pasta Calendário para criar o novo item de compromisso.
Defina a propriedade dispidApptRecur (PidLidAppointmentRecur) e outras propriedades necessárias para criar um compromisso recorrente.
Salve o novo item de compromisso.
A AddAppointment
função no arquivo de origem Appointments.cpp do projeto CreateOutlookItemsAddin demonstra essas etapas. A AddAppointment
função usa parâmetros da caixa de diálogo Adicionar Compromisso que é exibida quando você clica em Adicionar Compromisso no menu Addins no aplicativo de exemplo MFCMAPI. A DisplayAddAppointmentDialog
função em Appointments.cpp exibe a caixa de diálogo e passa valores da caixa de diálogo para a AddAppointment
função. A DisplayAddAppointmentDialog
função não se relaciona diretamente com a criação de um item de compromisso usando MAPI, portanto, ela não está listada aqui.
Importante
O código no aplicativo MFCMAPI não garante que a pasta Calendário tenha sido selecionada quando você clicar no comando Adicionar Compromisso no menu Addins . Criar um item de compromisso em uma pasta diferente da pasta Calendário pode causar um comportamento indefinido. Verifique se você selecionou a pasta Calendário antes de usar o comando Adicionar Compromisso no aplicativo MFCMAPI.
O AddAppointment
método está listado abaixo. Observe que o parâmetro lpFolder passado para o AddAppointment
método é um ponteiro para uma interface IMAPIFolder que representa a pasta em que o compromisso recorrente é criado. Dado o parâmetro lpFolder que representa uma interface IMAPIFolder , o código chama o método IMAPIFolder::CreateMessage . O método CreateMessage retorna um código de sucesso e um ponteiro para um ponteiro para uma interface IMessage . A maior parte do AddAppointment
código de função manipula o trabalho de especificar propriedades em preparação para chamar o método IMAPIProp::SetProps . Se a chamada para o método SetProps for bem-sucedida, o método IMAPIProp::SaveChanges será chamado para confirmar as alterações no repositório e criar um novo item de calendário.
A AddAppointment
função define várias propriedades nomeadas. Para obter informações sobre propriedades nomeadas e como elas são criadas, consulte Usando MAPI para criar itens do Outlook 2007. Como as propriedades nomeadas usadas para itens de compromisso ocupam vários conjuntos de propriedades, deve-se tomar cuidado ao criar parâmetros para passar para o método IMAPIProp::GetIDsFromNames .
A AddAppointment
função usa várias funções auxiliares para criar uma estrutura para várias propriedades relacionadas ao compromisso. As BuildTimeZoneStruct
funções auxiliares e BuildTimeZoneDefinition
são usadas para criar uma estrutura que especifica as propriedades relacionadas ao fuso horário. As propriedades relacionadas ao fuso horário são dispidTimeZoneStruct (PidLidTimeZoneStruct), dispidTimeZoneDesc (PidLidTimeZoneDescription), dispidApptTZDefRecur (PidLidAppointmentTimeZoneDefinitionRecur ), dispidApptTZDefStartDisplay (PidLidAppointmentTimeZoneDefinitionStartDisplay) e dispidApptTZDefEndDisplay (PidLidAppointmentTimeZoneDefinitionEndDisplay) e eles são discutidos no as seções correspondentes de [MS-OXOCAL].
A BuildGlobalObjectID
função é usada para criar uma estrutura que especifica as propriedades LID_GLOBAL_OBJID (PidLidGlobalObjectId) e dispidCleanGlobalObjId (PidLidCleanGlobalObjectId), que são discutidas nas seções correspondentes de [MS-OXOCAL]. A estrutura que especifica a propriedade dispidApptRecur é criada usando a BuildWeeklyAppointmentRecurrencePattern
função.
Para obter informações sobre a estrutura criada pela BuildWeeklyAppointmentRecurrencePattern
função, consulte Propriedade Canônica PidLidAppointmentRecur. Observe que, embora uma grande variedade de padrões de recorrência de compromisso seja possível, a BuildWeeklyAppointmentRecurrencePattern
função só cria um padrão de recorrência de compromisso semanal. Ele também usa vários valores codificados, como o tipo de calendário (gregoriano), o primeiro dia da semana (domingo) e o número de instâncias modificadas ou excluídas (nenhuma). Uma função de criação de padrão de recorrência de compromisso de finalidade mais geral precisaria aceitar esses tipos de variáveis como parâmetros.
A seguir está a listagem completa da AddAppointment
função.
HRESULT AddAppointment(LPMAPIFOLDER lpFolder,
SYSTEMTIME* lpstStartDateLocal, // PidLidAppointmentRecur
SYSTEMTIME* lpstEndDateLocal, // PidLidAppointmentRecur
SYSTEMTIME* lpstStartFirstUST, // PidLidAppointmentStartWhole, PidLidCommonStart, PR_START_DATE
SYSTEMTIME* lpstEndFirstUST, // PidLidAppointmentEndWhole, PidLidCommonEnd, PR_END_DATE
SYSTEMTIME* lpszClipStartUST, // PidLidClipStart
SYSTEMTIME* lpstClipEndUST, // PidLidClipEnd
SYSTEMTIME* lpstFirstDOW, // PidLidAppointmentRecur
DWORD dwStartOffsetLocal, // PidLidAppointmentRecur
DWORD dwEndOffsetLocal, // PidLidAppointmentRecur
DWORD dwPeriod, // PidLidAppointmentRecur
DWORD dwOccurrenceCount, // PidLidAppointmentRecur
DWORD dwPatternTypeSpecific, // PidLidAppointmentRecur
ULONG ulDuration, // PidLidAppointmentDuration
LPWSTR szSubject, // PR_SUBJECT_W
LPWSTR szLocation, // PidLidLocation
LPWSTR szPattern) // PidLidRecurrencePattern
{
if (!lpFolder) return MAPI_E_INVALID_PARAMETER;
HRESULT hRes = S_OK;
LPMESSAGE lpMessage = 0;
// create a message and set its properties
hRes = lpFolder->CreateMessage(0,
0,
&lpMessage);
if (SUCCEEDED(hRes))
{
MAPINAMEID rgnmid[ulAppointmentProps];
LPMAPINAMEID rgpnmid[ulAppointmentProps];
LPSPropTagArray lpNamedPropTags = NULL;
ULONG i = 0;
for (i = 0 ; i < ulAppointmentProps ; i++)
{
if (i < ulFirstMeetingProp)
rgnmid[i].lpguid = (LPGUID)&PSETID_Appointment;
else if (i < ulFirstCommonProp)
rgnmid[i].lpguid = (LPGUID)&PSETID_Meeting;
else
rgnmid[i].lpguid = (LPGUID)&PSETID_Common;
rgnmid[i].ulKind = MNID_ID;
rgnmid[i].Kind.lID = aulAppointmentProps[i];
rgpnmid[i] = &rgnmid[i];
}
hRes = lpFolder->GetIDsFromNames(
ulAppointmentProps,
(LPMAPINAMEID*) &rgpnmid,
NULL,
&lpNamedPropTags);
if (SUCCEEDED(hRes) && lpNamedPropTags)
{
// Because the properties to be set are known in advance,
// most of the structures involved can be statically declared
// to minimize expensive MAPIAllocateBuffer calls.
SPropValue spvProps[NUM_PROPS] = {0};
spvProps[p_PidLidAppointmentSequence].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidAppointmentSequence],PT_LONG);
spvProps[p_PidLidBusyStatus].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidBusyStatus],PT_LONG);
spvProps[p_PidLidLocation].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidLocation],PT_UNICODE);
spvProps[p_PidLidAppointmentStartWhole].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidAppointmentStartWhole],PT_SYSTIME);
spvProps[p_PidLidAppointmentEndWhole].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidAppointmentEndWhole],PT_SYSTIME);
spvProps[p_PidLidAppointmentDuration].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidAppointmentDuration],PT_LONG);
spvProps[p_PidLidAppointmentColor].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidAppointmentColor],PT_LONG);
spvProps[p_PidLidResponseStatus].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidResponseStatus],PT_LONG);
spvProps[p_PidLidRecurring].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidRecurring],PT_BOOLEAN);
spvProps[p_PidLidClipStart].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidClipStart],PT_SYSTIME);
spvProps[p_PidLidClipEnd].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidClipEnd],PT_SYSTIME);
spvProps[p_PidLidTimeZoneStruct].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidTimeZoneStruct],PT_BINARY);
spvProps[p_PidLidTimeZoneDescription].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidTimeZoneDescription],PT_UNICODE);
spvProps[p_PidLidAppointmentTimeZoneDefinitionRecur].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidAppointmentTimeZoneDefinitionRecur],
PT_BINARY);
spvProps[p_PidLidAppointmentTimeZoneDefinitionStartDisplay].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidAppointmentTimeZoneDefinitionStartDisplay],
PT_BINARY);
spvProps[p_PidLidAppointmentTimeZoneDefinitionEndDisplay].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidAppointmentTimeZoneDefinitionEndDisplay],
PT_BINARY);
spvProps[p_PidLidAppointmentRecur].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidAppointmentRecur],PT_BINARY);
spvProps[p_PidLidRecurrenceType].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidRecurrenceType],PT_LONG);
spvProps[p_PidLidRecurrencePattern].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidRecurrencePattern],PT_UNICODE);
spvProps[p_PidLidIsRecurring].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidIsRecurring],PT_BOOLEAN);
spvProps[p_PidLidGlobalObjectId].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidGlobalObjectId],PT_BINARY);
spvProps[p_PidLidCleanGlobalObjectId].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidCleanGlobalObjectId],PT_BINARY);
spvProps[p_PidLidCommonStart].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidCommonStart],PT_SYSTIME);
spvProps[p_PidLidCommonEnd].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidCommonEnd],PT_SYSTIME);
spvProps[p_PidLidSideEffects].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidSideEffects],PT_LONG);
spvProps[p_PR_SUBJECT_W].ulPropTag = PR_SUBJECT_W;
spvProps[p_PR_START_DATE].ulPropTag = PR_START_DATE;
spvProps[p_PR_END_DATE].ulPropTag = PR_END_DATE;
spvProps[p_PR_MESSAGE_CLASS_W].ulPropTag = PR_MESSAGE_CLASS_W;
spvProps[p_PR_ICON_INDEX].ulPropTag = PR_ICON_INDEX;
spvProps[p_PR_CONVERSATION_INDEX].ulPropTag = PR_CONVERSATION_INDEX;
spvProps[p_PR_MESSAGE_FLAGS].ulPropTag = PR_MESSAGE_FLAGS;
spvProps[p_PidLidAppointmentSequence].Value.l = 0;
spvProps[p_PidLidBusyStatus].Value.l = olBusy;
spvProps[p_PidLidLocation].Value.lpszW = szLocation;
SystemTimeToFileTime(lpstStartFirstUST,&spvProps[p_PidLidAppointmentStartWhole].Value.ft);
SystemTimeToFileTime(lpstEndFirstUST,&spvProps[p_PidLidAppointmentEndWhole].Value.ft);
spvProps[p_PidLidAppointmentDuration].Value.l = ulDuration;
spvProps[p_PidLidAppointmentColor].Value.l = 0; // No color
spvProps[p_PidLidResponseStatus].Value.l = respNone;
spvProps[p_PidLidRecurring].Value.b = true;
SystemTimeToFileTime(lpszClipStartUST,&spvProps[p_PidLidClipStart].Value.ft);
SystemTimeToFileTime(lpstClipEndUST,&spvProps[p_PidLidClipEnd].Value.ft);
SYSTEMTIME stStandard = {0};
stStandard.wMonth = 0xB;
stStandard.wDay = 0x1;
stStandard.wHour = 0x2;
SYSTEMTIME stDaylight = {0};
stDaylight.wMonth = 0x3;
stDaylight.wDay = 0x2;
stDaylight.wHour = 0x2;
hRes = BuildTimeZoneStruct(
300,
0,
(DWORD)-60,
&stStandard,
&stDaylight,
&spvProps[p_PidLidTimeZoneStruct].Value.bin.cb,
&spvProps[p_PidLidTimeZoneStruct].Value.bin.lpb);
spvProps[p_PidLidTimeZoneDescription].Value.lpszW = L"(GMT-05:00) Eastern Time (US & Canada)";
SYSTEMTIME stRule1Standard = {0};
stRule1Standard.wMonth = 0xA;
stRule1Standard.wDay = 0x5;
stRule1Standard.wHour = 0x2;
SYSTEMTIME stRule1Daylight = {0};
stRule1Daylight.wMonth = 0x4;
stRule1Daylight.wDay = 0x1;
stRule1Daylight.wHour = 0x2;
if (SUCCEEDED(hRes)) hRes = BuildTimeZoneDefinition(
L"Eastern Standard Time",
0, // TZRule Flags
2006, // wYear
300, // lbias
0, // lStandardBias,
(DWORD)-60, // lDaylightBias,
&stRule1Standard, // stStandardDate
&stRule1Daylight, // stDaylightDate
TZRULE_FLAG_EFFECTIVE_TZREG, // TZRule Flags
2007, // wYear
300, // lbias
0, // lStandardBias,
(DWORD)-60, // lDaylightBias,
&stStandard, // stStandardDate
&stDaylight, // stDaylightDate
&spvProps[p_PidLidAppointmentTimeZoneDefinitionRecur].Value.bin.cb,
&spvProps[p_PidLidAppointmentTimeZoneDefinitionRecur].Value.bin.lpb);
spvProps[p_PidLidAppointmentTimeZoneDefinitionStartDisplay].Value.bin.cb
= spvProps[p_PidLidAppointmentTimeZoneDefinitionRecur].Value.bin.cb;
spvProps[p_PidLidAppointmentTimeZoneDefinitionStartDisplay].Value.bin.lpb
= spvProps[p_PidLidAppointmentTimeZoneDefinitionRecur].Value.bin.lpb;
spvProps[p_PidLidAppointmentTimeZoneDefinitionEndDisplay].Value.bin.cb
= spvProps[p_PidLidAppointmentTimeZoneDefinitionRecur].Value.bin.cb;
spvProps[p_PidLidAppointmentTimeZoneDefinitionEndDisplay].Value.bin.lpb
= spvProps[p_PidLidAppointmentTimeZoneDefinitionRecur].Value.bin.lpb;
if (SUCCEEDED(hRes)) hRes = BuildWeeklyAppointmentRecurrencePattern(
lpstStartDateLocal,
lpstEndDateLocal,
lpstFirstDOW,
dwStartOffsetLocal,
dwEndOffsetLocal,
dwPeriod,
dwOccurrenceCount,
dwPatternTypeSpecific,
&spvProps[p_PidLidAppointmentRecur].Value.bin.cb,
&spvProps[p_PidLidAppointmentRecur].Value.bin.lpb);
spvProps[p_PidLidRecurrenceType].Value.l = rectypeWeekly;
spvProps[p_PidLidRecurrencePattern].Value.lpszW = szPattern;
spvProps[p_PidLidIsRecurring].Value.b = true;
if (SUCCEEDED(hRes)) hRes = BuildGlobalObjectId(
&spvProps[p_PidLidGlobalObjectId].Value.bin.cb,
&spvProps[p_PidLidGlobalObjectId].Value.bin.lpb);
spvProps[p_PidLidCleanGlobalObjectId].Value.bin.cb = spvProps[p_PidLidGlobalObjectId].Value.bin.cb;
spvProps[p_PidLidCleanGlobalObjectId].Value.bin.lpb = spvProps[p_PidLidGlobalObjectId].Value.bin.lpb;
SystemTimeToFileTime(lpstStartFirstUST,&spvProps[p_PidLidCommonStart].Value.ft);
SystemTimeToFileTime(lpstEndFirstUST,&spvProps[p_PidLidCommonEnd].Value.ft);
spvProps[p_PidLidSideEffects].Value.l
= seOpenToDelete | seOpenToCopy | seOpenToMove | seCoerceToInbox | seOpenForCtxMenu;
spvProps[p_PR_SUBJECT_W].Value.lpszW = szSubject;
SystemTimeToFileTime(lpstStartFirstUST,&spvProps[p_PR_START_DATE].Value.ft);
SystemTimeToFileTime(lpstEndFirstUST,&spvProps[p_PR_END_DATE].Value.ft);
spvProps[p_PR_MESSAGE_CLASS_W].Value.lpszW = L"IPM.Appointment";
spvProps[p_PR_ICON_INDEX].Value.l = 0x00000401; // Recurring Appointment
if (SUCCEEDED(hRes)) hRes = BuildConversationIndex(
&spvProps[p_PR_CONVERSATION_INDEX].Value.bin.cb,
&spvProps[p_PR_CONVERSATION_INDEX].Value.bin.lpb);
spvProps[p_PR_MESSAGE_FLAGS].Value.l = MSGFLAG_READ;
if (SUCCEEDED(hRes)) hRes = lpMessage->SetProps(NUM_PROPS, spvProps, NULL);
if (SUCCEEDED(hRes))
{
hRes = lpMessage->SaveChanges(FORCE_SAVE);
}
if (spvProps[p_PidLidTimeZoneStruct].Value.bin.lpb)
delete[] spvProps[p_PidLidTimeZoneStruct].Value.bin.lpb;
if (spvProps[p_PidLidAppointmentTimeZoneDefinitionRecur].Value.bin.lpb)
delete[] spvProps[p_PidLidAppointmentTimeZoneDefinitionRecur].Value.bin.lpb;
// Do not delete p_PidLidAppointmentTimeZoneDefinitionStartDisplay,
// it was borrowed from p_PidLidAppointmentTimeZoneDefinitionStartDisplay
// Do not delete p_PidLidAppointmentTimeZoneDefinitionEndDisplay,
// it was borrowed from p_PidLidAppointmentTimeZoneDefinitionStartDisplay
if (spvProps[p_PidLidAppointmentRecur].Value.bin.lpb)
delete[] spvProps[p_PidLidAppointmentRecur].Value.bin.lpb;
if (spvProps[p_PidLidGlobalObjectId].Value.bin.lpb)
delete[] spvProps[p_PidLidGlobalObjectId].Value.bin.lpb;
// Do not delete p_PidLidCleanGlobalObjectId, it was borrowed from p_PidLidGlobalObjectId
if (spvProps[p_PR_CONVERSATION_INDEX].Value.bin.lpb)
delete[] spvProps[p_PR_CONVERSATION_INDEX].Value.bin.lpb;
}
MAPIFreeBuffer(lpNamedPropTags);
}
if (lpMessage) lpMessage->Release();
return hRes;
}