Use the template class to automatically update the COM connection point receiver (Sink)

Source: Internet
Author: User

Previously, the original author's code was further encapsulated by using the template class to automatically implement the COM connection point receiver (Sink), and the principle used by the connection point was clarified. During the process of viewing the ATL code, it is found that ATL itself provides a mechanism such as AtlAdvise/AtlUnadvise to simplify the use of connection points. In CComPtrBase, Advise is also a member function, which further encapsulates AtlAdvise. Therefore, the ConnectionHelper code can be simplified. After the code is simplified, Connect () is only 10 lines. The GetConnectPoint function written by the original author cannot be used.

#if !defined( __sinkimpl_h_INCLUDED__ )#define __sinkimpl_h_INCLUDED__ #if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000template<typename T, typename EventInterface, const GUID * evtLibID = NULL >class ATL_NO_VTABLE CSinkImpT: public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CSinkImpT<T, EventInterface, evtLibID>, &__uuidof(T)>, public IDispatchImpl < EventInterface, &__uuidof(EventInterface), evtLibID >{public:CSinkImpT() {}virtual ~CSinkImpT() {}typedef IDispatchImpl<EventInterface, &__uuidof(EventInterface), evtLibID> _parentClass;typedef CSinkImpT<T, EventInterface, evtLibID> _thisClass;STDMETHOD( Invoke )(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr){T * pThis = static_cast<T *>(this);return pThis->DoInvoke( dispidMember, riid,lcid, wFlags, pdispparams, pvarResult,pexcepinfo, puArgErr );}DECLARE_NO_REGISTRY()DECLARE_PROTECT_FINAL_CONSTRUCT()BEGIN_COM_MAP( _thisClass )COM_INTERFACE_ENTRY( IDispatch )COM_INTERFACE_ENTRY( EventInterface )END_COM_MAP();STDMETHOD( DoInvoke )(DISPID dispidMember, REFIID riid,   LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,   EXCEPINFO* pexcepinfo, UINT* puArgErr){return _parentClass::Invoke( dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr );}};///////////////////////////////////////////////////////////////////////////////////////////////////////// ComDllLib::ITestComPtr pCom;// HRESULT hr = pCom.CreateInstance( L"Test.Com" );// ConnectionPointHelper<ComDllLib::ITestCom, ComDllLib::_ITestComEvent, CSink3> cph( pCom );//template<typename EventInterface, typename EventProcessor>class ConnectionPointHelper{CComPtr<IUnknown> m_spInterface;DWORD m_dwCookie;public:ConnectionPointHelper( IUnknown* pInterface ) : m_spInterface( pInterface ), m_dwCookie( 0 ) { Connect(); }~ConnectionPointHelper() { Disconnect(); }protected:void Connect(){HRESULT hr = E_FAIL;do{if ( m_spInterface == NULL || m_dwCookie != 0 ) { break; }CComObject<EventProcessor> * pTmp = NULL;hr = CComObject<EventProcessor>::CreateInstance( &pTmp );if ( FAILED( hr ) ){ break; }CComQIPtr<IUnknown, &IID_IUnknown> spSink( pTmp );hr = m_spInterface.Advise( spSink, __uuidof(EventInterface), &m_dwCookie );} while ( FALSE );}void Disconnect(){HRESULT hr = E_FAIL;do {if ( m_dwCookie == 0 ) { break; }AtlUnadvise( m_spInterface, __uuidof(EventInterface), m_dwCookie );m_dwCookie = 0;} while ( FALSE );}};#endif // !defined( __sinkimpl_h_INCLUDED__ )

All the above Code is reduced to less than 100 lines.

 

Usage:

{//. Call ComDllLib: ITestComPtr pCom; CComPtr <IUnknown> pUnknown; HRESULT hr = pCom. createInstance (L "Test. com "); if (SUCCEEDED (hr) {hr = pCom-> QueryInterface (IID_IUnknown, reinterpret_cast <void **> (& pUnknown); if (SUCCEEDED (hr )) {ConnectionPointHelper <ComDllLib: _ ITestComEvent, CSink3> cph (pUnknown); LONG c = pCom-> Add (1, 5 );}}}

  

{// Call CComPtr <IDispatch> spDisp in IDispatch mode; HRESULT hr = spDisp. coCreateInstance (L "Test. com "); if (SUCCEEDED (hr) {CComQIPtr <IUnknown, & found> spUnknown (spDisp); ConnectionPointHelper <ComDllLib: _ Unknown, CSink3> cph (spUnknown ); _ variant_t ret; _ variant_t m = 2, n = 3; spDisp. invoke2 (LPCOLESTR) L "Add", & m, & n, & ret );}}

  

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.