2016-12-19 81 views
0

Outlook에서 보내기 단추를 누르는 경우 사용자가 메일 정보를 가져오고 값을 기반으로 일부 작업을 수행하려고합니다. 이이 작동ATL/COM C++ Outlook Addin에서 메일 항목에 액세스 할 수 없습니다.

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() 

: 나는

DispEventAdvise((IDispatch*)m_Application, &__uuidof(Outlook::ApplicationEvents)); 

그것은이 같은 헤더 파일에 구현되어 호출 즉, OnConnection 이벤트 핸들러에서

VOID WINAPI CConnect::ItemSend(IDispatch * Item, bool Cancel)

: 그러므로 나는이 기능을 사용 그냥해야하지만, 함수 안에는 메일 항목을 얻으려고 항상 예외가 생깁니다. 다음은 항목에 액세스하기위한 코드입니다.

CComPtr<Outlook::_MailItem> mail; 
Item->QueryInterface(IID__MailItem, (void**)&mail); 

무엇이 잘못 되었나요? 미리 감사드립니다

+0

'QueryInterface()'의'HRESULT' 반환 값은 무엇입니까? – Aurora

+0

불행히도 응용 프로그램이 항상 '0xC000041D : 사용자 콜백 중에 처리되지 않은 예외가 발생했습니다'와 충돌하기 때문에 아무 것도 반환하지 않습니다. – Bautzi89

+0

['QueryInterface()'] (https://msdn.microsoft.com/en-us) /library/windows/desktop/ms682521(v=vs.85).aspx)는 HRESULT를 반환하지만 값은 확인하지 않습니다. 'HRESULT hr = Item-> QueryInterface (IID__MailItem, (void **) &mail);')와 같이 코드를 편집하고 다음 줄에 중단 점을 넣어 'hr' 값을 확인하십시오. – Aurora

답변

1

문제가 발생할 수있는 코드에서주의 사항이 몇 가지있다 :

  • 귀하의 ItemSend() 방법은 Outlook의 형식 라이브러리에있는 것과 다릅니다가. ItemSend(IDispatch* Item, VARIANT_BOOL* Cancel)으로 선언해야합니다.
  • IDispEventSimpleImpl 템플릿 선언의 이벤트 dispinterface의 IID에 대한 포인터는 Outlook::ItemEvents을 가리 킵니다. 그러나 Outlook::ApplicationEvents에서 이벤트를 처리하는 데 관심이 있습니다.
  • 중요한 것은 아니지만 DispEventAdvise()을 호출하면 응용 프로그램 인터페이스 포인터가 IDispatch*으로 변경되지만 함수는 IUnknown* 매개 변수를 사용해야합니다. 두 번째 매개 변수를 생략 할 수도 있습니다.

다음 클래스는 그에 따라 ItemSend 이벤트를 처리하는 방법을 보여줍니다. IDTExtensibility2 인터페이스를 구현 중이므로 초기화 및 정리 루틴을 OnConnectionOnDisconnection 메소드로 각각 이동해야합니다.

_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; 
}; 
+0

You 귀하의 포인트와 절대적으로 맞습니다. 이전에 Outlook :: ApplicationEvents를 사용하려고했으나 정확하게 파악할 수 없었지만 코드 덕분에 지금 작동 중입니다. . 정말 고맙습니다! – Bautzi89

+0

잘 듣고 싶습니다. 귀하의 의견에 감사드립니다. – Aurora