Создание простого элемента повторяющейся задачи
Область применения: Outlook 2013 | Outlook 2016
MAPI можно использовать для создания элементов задачи. В этом разделе описывается создание простого элемента повторяющейся задачи.
Сведения о том, как скачать, просмотреть и запустить код из приложения MFCMAPI и проекта CreateOutlookItemsAddin, упоминаемого в этом разделе, см. в разделе Установка примеров, используемых в этом разделе.
Создание элемента задачи
Откройте хранилище сообщений. Сведения об открытии хранилища сообщений см. в разделе Открытие хранилища сообщений.
Откройте папку Задачи в хранилище сообщений. Дополнительные сведения см. в разделе PR_IPM_TASK_ENTRYID (PidTagIpmTaskEntryId).
Вызовите метод IMAPIFolder::CreateMessage в папке Tasks, чтобы создать новый элемент задачи.
Задайте свойство dispidTaskRecur (PidLidTaskRecurrence) и другие связанные с задачей свойства, необходимые для создания повторяющейся задачи.
Сохраните новый элемент задачи.
Эти AddTask
шаги демонстрирует функция в исходном файле Tasks.cpp проекта CreateOutlookItemsAddin. Функция AddTask
принимает параметры из диалогового окна Добавление задачи , которое отображается при нажатии кнопки Добавить задачу в меню Addins в примере приложения MFCMAPI. Функция DisplayAddTaskDialog
в Tasks.cpp отображает диалоговое окно и передает значения из диалогового окна функции AddTask
. Функция DisplayAddTaskDialog
не связана напрямую с созданием элемента задачи с помощью MAPI, поэтому она не указана здесь.
Важно!
Код в приложении MFCMAPI не гарантирует, что папка "Задачи " выбрана при нажатии команды "Добавить задачу " в меню "Надстройки ". Создание элементов задач в папке, отличной от папки "Задачи", может привести к неопределенному поведению. Убедитесь, что вы выбрали папку Задачи , прежде чем использовать команду Добавить задачу в приложении MFCMAPI.
Функция AddTask
приведена ниже. Обратите внимание, что параметр lpFolder , передаваемый AddTask
в функцию, является указателем на интерфейс IMAPIFolder , представляющий папку, в которой создается новая задача. Учитывая lpFolder , представляющий интерфейс IMAPIFolder , код вызывает метод IMAPIFolder::CreateMessage . Метод CreateMessage возвращает код успешного выполнения и указатель на указатель на интерфейс IMessage . Большая часть AddTask
кода функции обрабатывает работу по указанию свойств при подготовке к вызову метода IMAPIProp::SetProps . Если вызов метода SetProps выполнен успешно, вызывается метод IMAPIProp::SaveChanges для фиксации изменений в хранилище и создания нового элемента задачи.
Функция AddTask
задает ряд именованных свойств. Сведения об именованных свойствах и способах их создания см. в статье Использование MAPI для создания элементов Outlook 2007. Так как именованные свойства, используемые для элементов задач, занимают несколько наборов свойств, при создании параметров необходимо соблюдать осторожность для передачи в метод IMAPIProp::GetIDsFromNames .
Функция AddTask
использует вспомогающую BuildWeeklyTaskRecurrencePattern
функцию для создания структуры, представляющей повторение задачи для задания свойства dispidTaskRecur . Сведения о структуре BuildWeeklyTaskRecurrencePattern
повторения задач, которую создает функция, см. в разделах Каноническое свойство PidLidTaskRecurrence и Каноническое свойство PidLidRecurrencePattern.
Обратите внимание, что хотя существует множество шаблонов повторения, BuildWeeklyTaskRecurrencePattern
функция создает только еженедельный шаблон повторения. Он также жестко закодирован для ряда предположений, таких как тип календаря (григорианский), первый день недели (воскресенье) и количество измененных или удаленных экземпляров (нет). Функция создания шаблона повторения общего назначения должна принимать такие переменные в качестве параметров.
Ниже приведен полный AddTask
список функции.
HRESULT AddTask(LPMAPIFOLDER lpFolder,
SYSTEMTIME* lpstStart, // PidLidCommonEnd, PidLidTaskDueDate, PidLidTaskRecurrence
SYSTEMTIME* lpstEnd, // PidLidTaskRecurrence
SYSTEMTIME* lpstFirstDOW, // PidLidTaskRecurrence
DWORD dwPeriod, // PidLidTaskRecurrence
DWORD dwOccurrenceCount, // PidLidTaskRecurrence
DWORD dwPatternTypeSpecific, // PidLidTaskRecurrence
LPWSTR szSubject, // PR_SUBJECT_W
LPWSTR szBody) // PR_BODY_W
{
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[ulTaskProps];
LPMAPINAMEID rgpnmid[ulTaskProps];
LPSPropTagArray lpNamedPropTags = NULL;
ULONG i = 0;
for (i = 0 ; i < ulTaskProps ; i++)
{
if (i < ulFirstTaskProp)
rgnmid[i].lpguid = (LPGUID)&PSETID_Common;
else
rgnmid[i].lpguid = (LPGUID)&PSETID_Task;
rgnmid[i].ulKind = MNID_ID;
rgnmid[i].Kind.lID = aulTaskProps[i];
rgpnmid[i] = &rgnmid[i];
}
hRes = lpFolder->GetIDsFromNames(
ulTaskProps,
(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_PidLidTaskMode].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidTaskMode],PT_LONG);
spvProps[p_PidLidCommonEnd].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidCommonEnd],PT_SYSTIME);
spvProps[p_PidLidTaskStatus].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidTaskStatus],PT_LONG);
spvProps[p_PidLidPercentComplete].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidPercentComplete],PT_DOUBLE);
spvProps[p_PidLidTaskState].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidTaskState],PT_LONG);
spvProps[p_PidLidTaskRecurrence].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidTaskRecurrence],PT_BINARY);
spvProps[p_PidLidTaskDeadOccurrence].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidTaskDeadOccurrence],PT_BOOLEAN);
spvProps[p_PidLidTaskOwner].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidTaskOwner],PT_UNICODE);
spvProps[p_PidLidTaskFRecurring].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidTaskFRecurring],PT_BOOLEAN);
spvProps[p_PidLidTaskOwnership].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidTaskOwnership],PT_LONG);
spvProps[p_PidLidTaskAcceptanceState].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidTaskAcceptanceState],PT_LONG);
spvProps[p_PidLidTaskFFixOffline].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidTaskFFixOffline],PT_BOOLEAN);
spvProps[p_PidLidTaskDueDate].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidTaskDueDate],PT_SYSTIME);
spvProps[p_PidLidTaskComplete].ulPropTag
= CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[p_PidLidTaskComplete],PT_SYSTIME);
spvProps[p_PR_MESSAGE_CLASS_W].ulPropTag = PR_MESSAGE_CLASS_W;
spvProps[p_PR_ICON_INDEX].ulPropTag = PR_ICON_INDEX;
spvProps[p_PR_SUBJECT_W].ulPropTag = PR_SUBJECT_W;
spvProps[p_PR_MESSAGE_FLAGS].ulPropTag = PR_MESSAGE_FLAGS;
spvProps[p_PR_BODY_W].ulPropTag = PR_BODY_W;
spvProps[p_PidLidTaskMode].Value.l = tdmtNothing;
SYSTEMTIME stStartUTC = {0};
TzSpecificLocalTimeToSystemTime(NULL,lpstStart,&stStartUTC);
SystemTimeToFileTime(&stStartUTC,&spvProps[p_PidLidCommonEnd].Value.ft);
spvProps[p_PidLidTaskStatus].Value.l = tsvNotStarted;
spvProps[p_PidLidPercentComplete].Value.dbl = 0.0;
spvProps[p_PidLidTaskState].Value.l = tdsOWNNEW;
spvProps[p_PidLidTaskDeadOccurrence].Value.b = false;
spvProps[p_PidLidTaskOwner].Value.lpszW = L"Unknown";
spvProps[p_PidLidTaskFRecurring].Value.b = true;
spvProps[p_PidLidTaskOwnership].Value.l = tovNew;
spvProps[p_PidLidTaskAcceptanceState].Value.l = tdvNone;
spvProps[p_PidLidTaskFFixOffline].Value.b = true;
SystemTimeToFileTime(lpstStart,&spvProps[p_PidLidTaskDueDate].Value.ft);
spvProps[p_PidLidTaskComplete].Value.b = false;
spvProps[p_PR_MESSAGE_CLASS_W].Value.lpszW = L"IPM.Task";
spvProps[p_PR_ICON_INDEX].Value.l = 0x501; // Unassigned Recurring Task
spvProps[p_PR_SUBJECT_W].Value.lpszW = szSubject;
spvProps[p_PR_MESSAGE_FLAGS].Value.l = MSGFLAG_READ;
spvProps[p_PR_BODY_W].Value.lpszW = szBody;
hRes = BuildWeeklyTaskRecurrencePattern(
lpstStart,
lpstEnd,
lpstFirstDOW,
dwPeriod,
dwOccurrenceCount,
dwPatternTypeSpecific,
&spvProps[p_PidLidTaskRecurrence].Value.bin.cb,
&spvProps[p_PidLidTaskRecurrence].Value.bin.lpb);
if (SUCCEEDED(hRes))
{
hRes = lpMessage->SetProps(NUM_PROPS, spvProps, NULL);
if (SUCCEEDED(hRes))
{
hRes = lpMessage->SaveChanges(FORCE_SAVE);
}
}
if (spvProps[p_PidLidTaskRecurrence].Value.bin.lpb)
delete[] spvProps[p_PidLidTaskRecurrence].Value.bin.lpb;
}
MAPIFreeBuffer(lpNamedPropTags);
}
if (lpMessage) lpMessage->Release();
return hRes;
}