Поделиться через


Создание простого элемента повторяющейся задачи

Область применения: Outlook 2013 | Outlook 2016

MAPI можно использовать для создания элементов задачи. В этом разделе описывается создание простого элемента повторяющейся задачи.

Сведения о том, как скачать, просмотреть и запустить код из приложения MFCMAPI и проекта CreateOutlookItemsAddin, упоминаемого в этом разделе, см. в разделе Установка примеров, используемых в этом разделе.

Создание элемента задачи

  1. Откройте хранилище сообщений. Сведения об открытии хранилища сообщений см. в разделе Открытие хранилища сообщений.

  2. Откройте папку Задачи в хранилище сообщений. Дополнительные сведения см. в разделе PR_IPM_TASK_ENTRYID (PidTagIpmTaskEntryId).

  3. Вызовите метод IMAPIFolder::CreateMessage в папке Tasks, чтобы создать новый элемент задачи.

  4. Задайте свойство dispidTaskRecur (PidLidTaskRecurrence) и другие связанные с задачей свойства, необходимые для создания повторяющейся задачи.

  5. Сохраните новый элемент задачи.

Эти 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;
}

См. также