Outlook 插件:DispEventAdvise 异常

发布于 2024-09-01 10:20:13 字数 3600 浏览 3 评论 0原文

我想创建一个插件来捕获{联系人、日历、任务、注释}的{创建、编辑、删除}时间。我有以下代码,为了使其更短,我删除了除与联系人相关的所有代码,因为我猜所有类型都是相同的。

AutoSync.h

class ATL_NO_VTABLE AutoSync : 
 public wxPanel,
 public IDispEventSimpleImpl<1, AutoSync, &__uuidof(Outlook::ItemsEvents)>,
 public IDispEventSimpleImpl<2, AutoSync, &__uuidof(Outlook::ItemsEvents)>,
 public IDispEventSimpleImpl<3, AutoSync, &__uuidof(Outlook::ItemsEvents)>
{
public:
 AutoSync();
 ~AutoSync();

 void __stdcall OnItemAdd(IDispatch* Item); /* 0xf001 */
 void __stdcall OnItemChange(IDispatch* Item); /* 0xf002 */ 
 void __stdcall OnItemRemove(); /* 0xf003 */

 BEGIN_SINK_MAP(AutoSync)
  SINK_ENTRY_INFO(1, __uuidof(Outlook::ItemsEvents), 0xf001, OnItemAdd, &OnItemsAddInfo)
  SINK_ENTRY_INFO(2, __uuidof(Outlook::ItemsEvents), 0xf002, OnItemChange, &OnItemsChangeInfo)
  SINK_ENTRY_INFO(3, __uuidof(Outlook::ItemsEvents), 0xf003, OnItemRemove, &OnItemsRemoveInfo)
 END_SINK_MAP()

 typedef IDispEventSimpleImpl<1, AutoSync, &__uuidof(Outlook::ItemsEvents)> ItemAddEvents;
 typedef IDispEventSimpleImpl<2, AutoSync, &__uuidof(Outlook::ItemsEvents)> ItemChangeEvents;
 typedef IDispEventSimpleImpl<3, AutoSync, &__uuidof(Outlook::ItemsEvents)> ItemRemoveEvents;

    private:

    CComPtr<Outlook::_Items> m_contacts;

    };

AutoSync.cpp

 _NameSpacePtr pMAPI = OutlookWorker::GetInstance()->GetNameSpacePtr();


MAPIFolderPtr pContactsFolder = NULL;
 HRESULT hr = NULL;

 //get folders
 if(pMAPI != NULL) {
  pMAPI->GetDefaultFolder(olFolderContacts, &pContactsFolder);
 }

 //get items
 if(pContactsFolder != NULL) pContactsFolder->get_Items(&m_contacts);

 //dispatch events
 if(m_contacts != NULL) {
    //HERE COMES THE EXCEPTION
  hr = ItemAddEvents::DispEventAdvise((IDispatch*)m_contacts,&__uuidof(Outlook::ItemsEvents));
  hr = ItemChangeEvents::DispEventAdvise((IDispatch*)m_contacts,&__uuidof(Outlook::ItemsEvents));
  hr = ItemRemoveEvents::DispEventAdvise((IDispatch*)m_contacts,&__uuidof(Outlook::ItemsEvents));
 }

在其他地方定义:

extern _ATL_FUNC_INFO OnItemsAddInfo;
extern _ATL_FUNC_INFO OnItemsChangeInfo;
extern _ATL_FUNC_INFO OnItemsRemoveInfo;
_ATL_FUNC_INFO OnItemsAddInfo = {CC_STDCALL,VT_EMPTY,1,{VT_DISPATCH}};
_ATL_FUNC_INFO OnItemsChangeInfo = {CC_STDCALL,VT_EMPTY,1,{VT_DISPATCH}};
_ATL_FUNC_INFO OnItemsRemoveInfo = {CC_STDCALL,VT_EMPTY,0};

问题出现

    hr = ItemAddEvents::DispEventAdvise((IDispatch*)m_contacts,&__uuidof(Outlook::ItemsEvents));
  hr = ItemChangeEvents::DispEventAdvise((IDispatch*)m_contacts,&__uuidof(Outlook::ItemsEvents));
  hr = ItemRemoveEvents::DispEventAdvise((IDispatch*)m_contacts,&__uuidof(Outlook::ItemsEvents));

在执行方法“Advise”时,它在“atlbase.inl”中给出异常:

ATLINLINE ATLAPI AtlAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw)
{
 if(pUnkCP == NULL)
  return E_INVALIDARG;

 CComPtr<IConnectionPointContainer> pCPC;
 CComPtr<IConnectionPoint> pCP;
 HRESULT hRes = pUnkCP->QueryInterface(__uuidof(IConnectionPointContainer), (void**)&pCPC);
 if (SUCCEEDED(hRes))
  hRes = pCPC->FindConnectionPoint(iid, &pCP);
 if (SUCCEEDED(hRes))
    //HERE GIVES EXCEPTION
    //Unhandled exception at 0x2fe913e3 in OUTLOOK.EXE: 0xC0000005: 
    //Access violation reading location 0xcdcdcdcd.
  hRes = pCP->Advise(pUnk, pdw);
 return hRes;
}

我无法理解为什么。这里有什么建议吗?一切似乎都很好,但显然并非如此。我已经被困在这里很长一段时间了。需要你的帮助,谢谢。

I want to creating an addin that captures when a {contact, calendar, task, note} is {created, edited, removed}. I have the following code, to make it shorter I removed all the code but the related to contact, since all types will be the same I guess.

AutoSync.h

class ATL_NO_VTABLE AutoSync : 
 public wxPanel,
 public IDispEventSimpleImpl<1, AutoSync, &__uuidof(Outlook::ItemsEvents)>,
 public IDispEventSimpleImpl<2, AutoSync, &__uuidof(Outlook::ItemsEvents)>,
 public IDispEventSimpleImpl<3, AutoSync, &__uuidof(Outlook::ItemsEvents)>
{
public:
 AutoSync();
 ~AutoSync();

 void __stdcall OnItemAdd(IDispatch* Item); /* 0xf001 */
 void __stdcall OnItemChange(IDispatch* Item); /* 0xf002 */ 
 void __stdcall OnItemRemove(); /* 0xf003 */

 BEGIN_SINK_MAP(AutoSync)
  SINK_ENTRY_INFO(1, __uuidof(Outlook::ItemsEvents), 0xf001, OnItemAdd, &OnItemsAddInfo)
  SINK_ENTRY_INFO(2, __uuidof(Outlook::ItemsEvents), 0xf002, OnItemChange, &OnItemsChangeInfo)
  SINK_ENTRY_INFO(3, __uuidof(Outlook::ItemsEvents), 0xf003, OnItemRemove, &OnItemsRemoveInfo)
 END_SINK_MAP()

 typedef IDispEventSimpleImpl<1, AutoSync, &__uuidof(Outlook::ItemsEvents)> ItemAddEvents;
 typedef IDispEventSimpleImpl<2, AutoSync, &__uuidof(Outlook::ItemsEvents)> ItemChangeEvents;
 typedef IDispEventSimpleImpl<3, AutoSync, &__uuidof(Outlook::ItemsEvents)> ItemRemoveEvents;

    private:

    CComPtr<Outlook::_Items> m_contacts;

    };

AutoSync.cpp

 _NameSpacePtr pMAPI = OutlookWorker::GetInstance()->GetNameSpacePtr();


MAPIFolderPtr pContactsFolder = NULL;
 HRESULT hr = NULL;

 //get folders
 if(pMAPI != NULL) {
  pMAPI->GetDefaultFolder(olFolderContacts, &pContactsFolder);
 }

 //get items
 if(pContactsFolder != NULL) pContactsFolder->get_Items(&m_contacts);

 //dispatch events
 if(m_contacts != NULL) {
    //HERE COMES THE EXCEPTION
  hr = ItemAddEvents::DispEventAdvise((IDispatch*)m_contacts,&__uuidof(Outlook::ItemsEvents));
  hr = ItemChangeEvents::DispEventAdvise((IDispatch*)m_contacts,&__uuidof(Outlook::ItemsEvents));
  hr = ItemRemoveEvents::DispEventAdvise((IDispatch*)m_contacts,&__uuidof(Outlook::ItemsEvents));
 }

somewhere else defined:

extern _ATL_FUNC_INFO OnItemsAddInfo;
extern _ATL_FUNC_INFO OnItemsChangeInfo;
extern _ATL_FUNC_INFO OnItemsRemoveInfo;
_ATL_FUNC_INFO OnItemsAddInfo = {CC_STDCALL,VT_EMPTY,1,{VT_DISPATCH}};
_ATL_FUNC_INFO OnItemsChangeInfo = {CC_STDCALL,VT_EMPTY,1,{VT_DISPATCH}};
_ATL_FUNC_INFO OnItemsRemoveInfo = {CC_STDCALL,VT_EMPTY,0};

The problems comes in the

    hr = ItemAddEvents::DispEventAdvise((IDispatch*)m_contacts,&__uuidof(Outlook::ItemsEvents));
  hr = ItemChangeEvents::DispEventAdvise((IDispatch*)m_contacts,&__uuidof(Outlook::ItemsEvents));
  hr = ItemRemoveEvents::DispEventAdvise((IDispatch*)m_contacts,&__uuidof(Outlook::ItemsEvents));

It gives exception in 'atlbase.inl' when executes method 'Advise':

ATLINLINE ATLAPI AtlAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw)
{
 if(pUnkCP == NULL)
  return E_INVALIDARG;

 CComPtr<IConnectionPointContainer> pCPC;
 CComPtr<IConnectionPoint> pCP;
 HRESULT hRes = pUnkCP->QueryInterface(__uuidof(IConnectionPointContainer), (void**)&pCPC);
 if (SUCCEEDED(hRes))
  hRes = pCPC->FindConnectionPoint(iid, &pCP);
 if (SUCCEEDED(hRes))
    //HERE GIVES EXCEPTION
    //Unhandled exception at 0x2fe913e3 in OUTLOOK.EXE: 0xC0000005: 
    //Access violation reading location 0xcdcdcdcd.
  hRes = pCP->Advise(pUnk, pdw);
 return hRes;
}

I can't manage to understand why. Any sugestion here? Everything seems to be fine, but obviously is not. I've been stucked here for quite a long time. Need your help, thanks.

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

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

发布评论

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

评论(3

薄荷→糖丶微凉 2024-09-08 10:20:13

快速浏览后的第一个事实是,您只需要从每个接口派生一个 IDispEventSimpleImpl - 您不需要为接口中的每个方法派生一个:

class ATL_NO_VTABLE AutoSync : 
  public wxPanel,
  public IDispEventSimpleImpl<1, AutoSync, &__uuidof(Outlook::ItemsEvents)>
{
public:
  // ...
  BEGIN_SINK_MAP(AutoSync)
    SINK_ENTRY_INFO(1, __uuidof(Outlook::ItemsEvents), 0xf001, OnItemAdd, &OnItemsAddInfo)
    SINK_ENTRY_INFO(1, __uuidof(Outlook::ItemsEvents), 0xf002, OnItemChange, &OnItemsChangeInfo)
    SINK_ENTRY_INFO(1, __uuidof(Outlook::ItemsEvents), 0xf003, OnItemRemove, &OnItemsRemoveInfo)
  END_SINK_MAP()

  typedef IDispEventSimpleImpl<1, AutoSync, &__uuidof(Outlook::ItemsEvents)> ItemAddEvents;
  // ...
};

再尝试一次简化。

The first fact from a quick look is that you only need to derive from one IDispEventSimpleImpl per interface - you don't need one for every method in the interface:

class ATL_NO_VTABLE AutoSync : 
  public wxPanel,
  public IDispEventSimpleImpl<1, AutoSync, &__uuidof(Outlook::ItemsEvents)>
{
public:
  // ...
  BEGIN_SINK_MAP(AutoSync)
    SINK_ENTRY_INFO(1, __uuidof(Outlook::ItemsEvents), 0xf001, OnItemAdd, &OnItemsAddInfo)
    SINK_ENTRY_INFO(1, __uuidof(Outlook::ItemsEvents), 0xf002, OnItemChange, &OnItemsChangeInfo)
    SINK_ENTRY_INFO(1, __uuidof(Outlook::ItemsEvents), 0xf003, OnItemRemove, &OnItemsRemoveInfo)
  END_SINK_MAP()

  typedef IDispEventSimpleImpl<1, AutoSync, &__uuidof(Outlook::ItemsEvents)> ItemAddEvents;
  // ...
};

Try again with that simplification.

迟月 2024-09-08 10:20:13

我遇到了类似的问题,原因是我从构造函数中调用虚拟方法。如果您的问题代码位于构造函数中,请尝试将其移至 FinalConstruct()。

I had a similar problem, the reason was I was calling virtual methods from within the constructor. If your code in question is in the constructor, try moving it to FinalConstruct().

长途伴 2024-09-08 10:20:13

我曾经遇到过这个异常,删除 ATL_NO_VTABLE 可以修复它。

I ever ran into this exception, removing ATL_NO_VTABLE can fix it.

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