【问题标题】:Outlook Addin: DispEventAdvise exceptionOutlook 插件:DispEventAdvise 异常
【发布时间】:2011-02-19 15:28:03
【问题描述】:

我想创建一个插件来捕获 {contact, calendar, task, note} 何时{创建、编辑、删除}。我有以下代码,为了缩短代码,我删除了所有代码,但与联系人相关,因为我猜所有类型都是相同的。

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;
}

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

【问题讨论】:

    标签: c++ events visual-c++ atl outlook-addin


    【解决方案1】:

    快速浏览的第一个事实是,您只需为每个接口派生一个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;
      // ...
    };
    

    用那个简化再试一次。

    【讨论】:

    • 简化完成,但仍然是同样的例外。还有其他想法吗?
    • @framara:如果不稍后挖出一个测试项目,就不是真的。在黑暗中随机拍摄将在删除 wxPanel 的情况下进行测试。
    • wxPanel 已删除且无法正常工作,仍然是相同的异常。无论如何,谢谢你,我真的很感激;)
    • 我只是在这里随机拍摄。调试时,-this -ATL::IDispEventSimpleImpl<...> -ATL::_IDispEventLocator<...> -ATL::_IDispEvent +__vfptr 0xcdcdcdcd +m_libid {GUID_NULL} +m_iid {GUID_NULL} m_wMayorVerNum 0x0000 m_wMinorVerNum 0x0000 m_dwEventCookie 0xfefefefe 也许它根本没有任何关系,但是对我来说看起来有点奇怪/不好,不是吗?编辑:我上传了一张图片,因为评论的格式有点复杂,yfrog.com/2sdebugj
    • 很奇怪,但可能是调试器以及一些损坏。我想在周末之前不能真正研究它,遗憾的是它没有快速的过程来为 Outlook 插件设置一个新的测试项目。还有一个newsgroup(但没有太多关于 C++/ATL 细节的反馈afair),也许 MSDN 社交论坛上有更多活动?
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-10-26
        • 1970-01-01
        • 2014-04-23
        • 1970-01-01
        • 2015-04-24
        • 2013-08-24
        • 2013-11-29
        相关资源
        最近更新 更多