首页 > 代码库 > 借助模板类自动实现COM连接点接收器(Sink)更新
借助模板类自动实现COM连接点接收器(Sink)更新
之前在借助模板类自动实现COM连接点接收器(Sink)中对原作者的代码进一步封装,弄清了连接点使用的原理,在看ATL代码的过程中,发现ATL本身就提供了AtlAdvise/AtlUnadvise这样的机制来简化连接点的使用,CComPtrBase中也有Advise这个成员函数,它是对AtlAdvise,进一步封装,因此,对ConnectionHelper的代码可以再简化,简化后Connect()只有十来行了。原作者写的GetConnectPoint函数也用不上了。
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | #if !defined( __sinkimpl_h_INCLUDED__ ) #define __sinkimpl_h_INCLUDED__ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 template < 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__ ) |
以上就是全部代码,减少到不到100行。
使用方法:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | { // .tlh中的接口方式调用 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 ); } } } |
?
1 2 3 4 5 6 7 8 9 10 11 12 | { // IDispatch方式调用 CComPtr<IDispatch> spDisp; HRESULT hr = spDisp.CoCreateInstance( L "Test.Com" ); if ( SUCCEEDED( hr ) ) { CComQIPtr<IUnknown, &IID_IUnknown> spUnknown( spDisp ); ConnectionPointHelper<ComDllLib::_ITestComEvent, CSink3> cph( spUnknown ); _variant_t ret; _variant_t m = 2, n = 3; spDisp.Invoke2( (LPCOLESTR) L "Add" , &m, &n, &ret ); } } |
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。