Outlook 插件。如何管理项目事件

发布于 2024-08-31 21:52:17 字数 2476 浏览 9 评论 0原文

我正在用 C++ 编写 Outlook 2007 的插件。

我需要捕获 Outlook 项目(联系人、约会、任务和注释)中的创建、更改或删除等事件,但我找到的唯一信息/示例适用于 Visual Basic,因此我不知道如何连接该事件处理程序。

以下是一些相关信息: http://msdn .microsoft.com/en-us/library/bb208390(v=office.12).aspx

欢迎任何帮助:) 谢谢

更新

抱歉花了这么长时间才更新,我'我已经出城了。我有一些疑问/问题,您可能知道如何提供帮助。

就我而言,我正在开展这个已经开始的项目,所以我对这一切有点困惑。我有从 IDTEXtensibility2 派生的 OutlookAddin 类。我还有另一个类,称为 AutoSync,我想在事件触发时执行所有方法等等。此类的对象在 OutlookAddin.cpp OnStartupComplete 中初始化。

根据您的帖子,MyClass 应该从 IDispEventSimpleImpl<1 /*N*/, MyClass, &__uuidof(Outlook::ItemsEvents)> 扩展,但其中哪一个? OutlookAddin 还是自动同步?

我还应该把这段代码放在哪里?

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,其中保存所有环境。

这里的预期行为是在创建/编辑/删除 ContactItem 时从 OutlookAddin 类触发函数“OnItemChange”,但这并没有发生...我对结构做了一些更改,所有内容都在主类 OutlookAddin 中。然后,在“OnItemChange”函数上,我将启动我之前告诉过您的“AutoSync”对象。

不管怎样,我正在关注你给我的文章,非常有用,谢谢。您还有其他建议给我吗?

谢谢你的耐心。

I'm doing an add-in for Outlook 2007 in C++.

I need to capture the events like create, change or delete from the Outlook Items (Contact, Appointment, Tasks and Notes) but the only information/examples I've found are for Visual Basic so I don't know how to connect the event handler.

Here is some information related: http://msdn.microsoft.com/en-us/library/bb208390(v=office.12).aspx

Any help is welcome :) Thanks

Update

Sorry for taking this long to update, I've been out of town. I have some doubts/problems that you may know how to help.

In my case, I'm taking this project that was started so I'm a bit confused about all this. I have the class OutlookAddin that derives from IDTExtensibility2. I also have this other class, called AutoSync, were I'd like to do all the methods when the event fires and so. An object of this class is initialized in OutlookAddin.cpp OnStartupComplete.

According to your post MyClass should extends from IDispEventSimpleImpl<1 /*N*/, MyClass, &__uuidof(Outlook::ItemsEvents)> but which one of them? OutlookAddin or AutoSync ?

Where I should put this code also?

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;

I've read the links you posted but still having these doubts...

Update 2

This is more complicated to understand than I though in a first instance.

So I have like this:

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' is defined like:

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

then in OutlookAddin.cpp, OnConnection method:

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

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

being 'OutlookWorker::GetInstance()->GetNameSpacePtr()' the _NameSpacePtr where all the environment is kept.

The expected behaviour here is to fire the function 'OnItemChange' from OutlookAddin class when an ContactItem is created/edited/deleted but that's not happening... I changed a little bit the structure to everything is in the main class OutlookAddin. Then on the function 'OnItemChange' I'll start the object of 'AutoSync' that I told you before.

Anyway I'm following the articles you gave me, really useful, thank you. Do you still have any other suggestion for me?

Thanks your patience.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷夜 2024-09-07 21:52:17

已经有一段时间了,但是您应该通过建议 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 在此标识您的接收器。然后还有剩余的宏要设置和处理程序函数要实现的乐趣 - 我建议您参考 文章中的示例和< code>dispinterface ItemsEvents,您可以在 oleview.exe 中查找。


关于更新 1:
如果您想在 AutoSync 中接收事件,请在那里实现接口 - 您不需要将事件接收到任何特定实例。然而,你最了解你的设计:)
我个人只是将尽可能多的逻辑保留在中央插件类之外。

注册代码将进入实现事件的类的某些方法,然后在它应该开始接收事件时调用,而typedef 将例如很好地放置在类的声明中。


关于更新 2:

乍一看,它看起来基本正确,但 OnItemChange() 采用一个参数 - 一个 IDispatch

_ATL_FUNC_INFO AtlCallDispatch = {CC_STDCALL, VT_EMPTY, 1, {VT_DISPATCH}};

Its been a while, but you should get these item events by advising for 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));

Where your class MyClass derives from:

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

And MyItemEvents is:

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

N identifies your sink here. Then there is the joy of the remaining macros to setup and the handler functions to implement - i refer you to this and this article for examples and to the dispinterface ItemsEvents that you can look up in oleview.exe.


Regarding update 1:
If you want to receive the events in AutoSync, implement the interface there - you are not required to sink the events to any specific instance. However, you know your design best :)
I'd just personally keep as much logic out of the central addin class as possible.

The registration code would go into some method of the class implementing the events then and called whenever it should start to receive events, while the typedef would be e.g. well placed in the class' declaration.


Regarding update 2:

From a quick glance it looks mostly right, but OnItemChange() takes one parameter - an IDispatch:

_ATL_FUNC_INFO AtlCallDispatch = {CC_STDCALL, VT_EMPTY, 1, {VT_DISPATCH}};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文