Надстройка Outlook. Как управлять событиями предметов

Я делаю надстройку для Outlook 2007 на С++.

Мне нужно зафиксировать такие события, как создание, изменение или удаление из элементов Outlook (контакты, встречи, задачи и заметки), но единственная информация/примеры, которые я нашел, относятся к Visual Basic, поэтому я не знаю, как подключить событие обработчик.

Вот некоторая связанная информация: http://msdn.microsoft.com/en-us/library/bb208390(v=office.12).aspx

Любая помощь приветствуется :) Спасибо

Обновить

Извините, что так долго не обновлялся, меня не было в городе. У меня есть некоторые сомнения / проблемы, которые вы можете знать, как помочь.

В моем случае я беру этот проект, который был начат, поэтому я немного запутался во всем этом. У меня есть класс OutlookAddin, производный от IDTExtensibility2. У меня также есть другой класс, называемый AutoSync, где я хотел бы использовать все методы при возникновении события и так далее. Объект этого класса инициализируется в OutlookAddin.cpp OnStartupComplete.

Согласно вашему сообщению, MyClass должен простираться от IDispEventSimpleImpl<1 /*N*/, MyClass, &__uuidof(Outlook::ItemsEvents)>, но какой из них? OutlookAddin или AutoSync?

Где я должен поместить этот код также?

CComPtr<Outlook::MAPIFolder> folder;
// get the folder you're interested in
CComPtr<Outlook::_Items> items;
hr = folder->get_Items(&items);
hr = MyItemEvents::DispEventAdvise(items, &__uuidof(Outlook::ItemsEvents));

typedef IDispEventSimpleImpl<1 /*N*/, MyClass, 
          &__uuidof(Outlook::ItemsEvents)> MyItemEvents;

Я прочитал ссылки, которые вы разместили, но все еще сомневаюсь...

Обновление 2

Это сложнее понять, чем я, хотя в первую очередь.

Итак, у меня есть так:

OutlookAddin.h

class OutlookAddin : 
public IDTExtensibility2,
public IDispEventSimpleImpl<1, OutlookAddin, &__uuidof(Outlook::ItemEvents)>
...
BEGIN_SINK_MAP(OutlookAddin)
SINK_ENTRY_INFO(1, __uuidof(Outlook::ItemEvents), 0xf002, OutlookAddin::OnItemChange, &OnSimpleEventInfo)
END_SINK_MAP()
...
void __stdcall OnItemChange();

«OnSimpleEventInfo» определяется как:

extern _ATL_FUNC_INFO OnSimpleEventInfo;
_ATL_FUNC_INFO OnSimpleEventInfo = {CC_STDCALL,VT_EMPTY,0};

затем в OutlookAddin.cpp метод OnConnection:

    CComPtr<Outlook::MAPIFolder> folder;
CComPtr<Outlook::_Items> items;

OutlookWorker::GetInstance()->GetNameSpacePtr()->GetDefaultFolder(olFolderContacts, &folder);
folder->get_Items(&items);
DispEventAdvise(items, &__uuidof(Outlook::ItemsEvents));

будучи «OutlookWorker::GetInstance()->GetNameSpacePtr()» _NameSpacePtr, в котором хранится вся среда.

Ожидаемое поведение здесь - запустить функцию OnItemChange из класса OutlookAddin, когда ContactItem создается/редактируется/удаляется, но этого не происходит... Я немного изменил структуру, чтобы все было в основном классе OutlookAddin. Затем на функции «OnItemChange» я запущу объект «AutoSync», о котором я говорил вам ранее.

В любом случае, я слежу за статьями, которые вы мне дали, очень полезными, спасибо. У вас есть еще какие-нибудь предложения для меня?

Спасибо за ваше терпение.


person framara    schedule 06.05.2010    source источник


Ответы (1)


Прошло некоторое время, но вы должны получать эти события предметов, советуя для Folder.Items:

CComPtr<Outlook::MAPIFolder> folder;
// get the folder you're interested in
CComPtr<Outlook::_Items> items;
hr = folder->get_Items(&items);
hr = MyItemEvents::DispEventAdvise(items, &__uuidof(Outlook::ItemsEvents));

Откуда происходит ваш класс MyClass:

IDispEventSimpleImpl<1 /*N*/, MyClass, &__uuidof(Outlook::ItemsEvents)>

И MyItemEvents это:

typedef IDispEventSimpleImpl<1 /*N*/, MyClass, 
          &__uuidof(Outlook::ItemsEvents)> MyItemEvents;

N идентифицирует здесь ваш приемник. Затем нужно настроить оставшиеся макросы и реализовать функции обработчика — я отсылаю вас к эту и эту статью с примерами и dispinterface ItemsEvents что вы можете найти в oleview.exe.


Относительно обновления 1:
Если вы хотите получать события в AutoSync, реализуйте интерфейс там — вам не нужно передавать события в какой-либо конкретный экземпляр. Тем не менее, вы лучше всех разбираетесь в своем дизайне :)
Лично я бы просто постарался убрать как можно больше логики из центрального класса надстроек.

Регистрационный код будет входить в какой-либо метод класса, реализующий события, и вызываться всякий раз, когда он должен начать получать события, в то время как typedef будет, например. хорошо размещен в объявлении класса.


Об обновлении 2:

На первый взгляд это выглядит в основном правильно, но OnItemChange() принимает один параметр - IDispatch:

_ATL_FUNC_INFO AtlCallDispatch = {CC_STDCALL, VT_EMPTY, 1, {VT_DISPATCH}};
person Georg Fritzsche    schedule 06.05.2010
comment
Спасибо, я посмотрю на это ;) - person framara; 06.05.2010
comment
Вопрос снова обновлен с более подробной информацией о коде. Надеюсь, вы понимаете это лучше. Спасибо - person framara; 13.05.2010