Надстройка Outlook. Как управлять событиями предметов - PullRequest
2 голосов
/ 06 мая 2010

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

Мне нужно захватить такие события, как создание, изменение или удаление из элементов 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», о котором я говорил ранее.

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

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

1 Ответ

1 голос
/ 06 мая 2010

Прошло много времени, но вы должны получить эти события предмета, посоветовав для 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}};
...