无法访问 ATL/COM C++ Outlook 插件中的邮件项目
Can't access mail item in ATL/COM C++ Outlook Addin
我正在尝试获取邮件信息并根据用户在 Outlook 中点击发送按钮时的值执行一些操作。因此我使用这个函数:
VOID WINAPI CConnect::ItemSend(IDispatch * Item, bool Cancel)
在我调用的 OnConnection 事件处理程序中
DispEventAdvise((IDispatch*)m_Application, &__uuidof(Outlook::ApplicationEvents));
它在头文件中是这样实现的:
public IDispEventSimpleImpl<1, CConnect, &__uuidof(Outlook::ItemEvents)>
public:
VOID WINAPI ItemSend(IDispatch * Item, bool Cancel);
BEGIN_SINK_MAP(CConnect)
SINK_ENTRY_INFO(1, __uuidof(Outlook::ItemEvents), 0x0000F002, ItemSend, &fiMailItemEvents)
END_SINK_MAP()
这一切正常,但在我尝试获取邮件项目的函数中,我总是遇到异常。这是我访问项目的代码:
CComPtr<Outlook::_MailItem> mail;
Item->QueryInterface(IID__MailItem, (void**)&mail);
我做错了什么?提前致谢
您的代码中有一些警告可能会导致问题:
- 您的
ItemSend()
方法与 Outlook 类型库中的方法不同。它应该声明为 ItemSend(IDispatch* Item, VARIANT_BOOL* Cancel)
.
- 在您的
IDispEventSimpleImpl
模板声明中指向事件调度接口 IID 的指针指向 Outlook::ItemEvents
。但是,您有兴趣处理来自 Outlook::ApplicationEvents
. 的事件
- 虽然不重要,但您对
DispEventAdvise()
的调用将应用程序接口指针转换为 IDispatch*
,而该函数需要一个 IUnknown*
参数。您也可以省略第二个参数。
下面的class演示了如何相应地处理ItemSend
事件。由于您正在实现 IDTExtensibility2
接口,因此您需要将初始化和清理例程分别移至其 OnConnection
和 OnDisconnection
方法。
_ATL_FUNC_INFO fiMailItemEvents = { CC_STDCALL, VT_EMPTY, 2, { VT_DISPATCH, VT_BOOL | VT_BYREF } };
class CConect :
public ATL::IDispEventSimpleImpl<1, CConect, &(__uuidof(Outlook::ApplicationEvents))>
{
public:
CConect(Outlook::_ApplicationPtr piApp)
{
m_piApp = piApp;
DispEventAdvise((IUnknown*)m_piApp);
}
virtual ~CConect()
{
DispEventUnadvise((IUnknown*)m_piApp);
}
void __stdcall OnItemSend(IDispatch* Item, VARIANT_BOOL* Cancel)
{
CComPtr<Outlook::_MailItem> mail;
HRESULT hr = Item->QueryInterface(__uuidof(Outlook::_MailItem), (void**)&mail);
}
BEGIN_SINK_MAP(CConect)
SINK_ENTRY_INFO(1, __uuidof(Outlook::ApplicationEvents), 0x0000F002, OnItemSend, &fiMailItemEvents)
END_SINK_MAP()
private:
Outlook::_ApplicationPtr m_piApp;
};
我正在尝试获取邮件信息并根据用户在 Outlook 中点击发送按钮时的值执行一些操作。因此我使用这个函数:
VOID WINAPI CConnect::ItemSend(IDispatch * Item, bool Cancel)
在我调用的 OnConnection 事件处理程序中
DispEventAdvise((IDispatch*)m_Application, &__uuidof(Outlook::ApplicationEvents));
它在头文件中是这样实现的:
public IDispEventSimpleImpl<1, CConnect, &__uuidof(Outlook::ItemEvents)>
public:
VOID WINAPI ItemSend(IDispatch * Item, bool Cancel);
BEGIN_SINK_MAP(CConnect)
SINK_ENTRY_INFO(1, __uuidof(Outlook::ItemEvents), 0x0000F002, ItemSend, &fiMailItemEvents)
END_SINK_MAP()
这一切正常,但在我尝试获取邮件项目的函数中,我总是遇到异常。这是我访问项目的代码:
CComPtr<Outlook::_MailItem> mail;
Item->QueryInterface(IID__MailItem, (void**)&mail);
我做错了什么?提前致谢
您的代码中有一些警告可能会导致问题:
- 您的
ItemSend()
方法与 Outlook 类型库中的方法不同。它应该声明为ItemSend(IDispatch* Item, VARIANT_BOOL* Cancel)
. - 在您的
IDispEventSimpleImpl
模板声明中指向事件调度接口 IID 的指针指向Outlook::ItemEvents
。但是,您有兴趣处理来自Outlook::ApplicationEvents
. 的事件
- 虽然不重要,但您对
DispEventAdvise()
的调用将应用程序接口指针转换为IDispatch*
,而该函数需要一个IUnknown*
参数。您也可以省略第二个参数。
下面的class演示了如何相应地处理ItemSend
事件。由于您正在实现 IDTExtensibility2
接口,因此您需要将初始化和清理例程分别移至其 OnConnection
和 OnDisconnection
方法。
_ATL_FUNC_INFO fiMailItemEvents = { CC_STDCALL, VT_EMPTY, 2, { VT_DISPATCH, VT_BOOL | VT_BYREF } };
class CConect :
public ATL::IDispEventSimpleImpl<1, CConect, &(__uuidof(Outlook::ApplicationEvents))>
{
public:
CConect(Outlook::_ApplicationPtr piApp)
{
m_piApp = piApp;
DispEventAdvise((IUnknown*)m_piApp);
}
virtual ~CConect()
{
DispEventUnadvise((IUnknown*)m_piApp);
}
void __stdcall OnItemSend(IDispatch* Item, VARIANT_BOOL* Cancel)
{
CComPtr<Outlook::_MailItem> mail;
HRESULT hr = Item->QueryInterface(__uuidof(Outlook::_MailItem), (void**)&mail);
}
BEGIN_SINK_MAP(CConect)
SINK_ENTRY_INFO(1, __uuidof(Outlook::ApplicationEvents), 0x0000F002, OnItemSend, &fiMailItemEvents)
END_SINK_MAP()
private:
Outlook::_ApplicationPtr m_piApp;
};