博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
借助模板类自动实现COM连接点接收器(Sink)
阅读量:5995 次
发布时间:2019-06-20

本文共 4468 字,大约阅读时间需要 14 分钟。

本文的更新: (2014-06-09 17:09)

 

最初的代码源自的,作者封装了不少工作,但调用时的代码还可以再封装一下,最后只要拷贝并修改Sink实现类的Invoke就好了。

 

以下是这个代码的头文件 "sinkimpl.h",比free2000fly的"sinkimpl.h"多了一个模板类ConnectionPointerHelper<>

#if !defined( __sinkimpl_h_INCLUDED__ )#define __sinkimpl_h_INCLUDED__ #if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000template
class ATL_NO_VTABLE CSinkImpT : public CComObjectRootEx
, public CComCoClass
, &__uuidof(T)> , public IDispatchImpl < EventInterface, &__uuidof(EventInterface), evtLibID >{public: CSinkImpT() {} virtual ~CSinkImpT() {} typedef IDispatchImpl
_parentClass; typedef CSinkImpT
_thisClass; STDMETHOD( Invoke )(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr) { T * pThis = static_cast
(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 ); }};inline HRESULT WINAPI GetConnectPoint( IUnknown * pItf, const IID & rSinkIID, IConnectionPoint ** ppCP ){ HRESULT hr = E_FAIL; do { if ( pItf == NULL || ppCP == NULL ) { break; } CComQIPtr
spContainer; hr = pItf->QueryInterface( &spContainer ); if ( FAILED( hr ) ) { break; } hr = spContainer->FindConnectionPoint( rSinkIID, ppCP ); } while ( FALSE ); return hr;}///// 使用方法:// ComDllLib::ITestComPtr pCom;// HRESULT hr = pCom.CreateInstance( L"Test.Com" );// ConnectionPointHelper
cph( pCom );//template
class ConnectionPointHelper{ CComPtr
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; } CComQIPtr
spCP; hr = GetConnectPoint( m_spInterface, __uuidof(EventInterface), &spCP ); if ( FAILED( hr ) ){ break; } CComQIPtr
spSink; { CComObject
* pTmp = NULL; hr = CComObject
::CreateInstance( &pTmp ); if ( FAILED( hr ) ){ break; } pTmp->AddRef(); hr = pTmp->QueryInterface( &spSink ); pTmp->Release(); if ( FAILED( hr ) ){ break; } } spCP->Advise( spSink, &m_dwCookie ); } while ( FALSE ); } void Disconnect() { HRESULT hr = E_FAIL; do { if ( m_dwCookie == 0 ) { break; } CComQIPtr
spCP; hr = GetConnectPoint( m_spInterface, __uuidof(EventInterface), &spCP ); if ( FAILED( hr ) ){ break; } hr = spCP->Unadvise( m_dwCookie ); m_dwCookie = 0; } while ( FALSE ); }};#endif // !defined( __sinkimpl_h_INCLUDED__ )

  

使用方法:
UIAddChildWindowContainer( m_hWnd );		ComDllLib::ITestComPtr pCom;		CComPtr
pUnknown; HRESULT hr = pCom.CreateInstance( L"Test.Com" ); if (SUCCEEDED(hr)) { hr = pCom->QueryInterface( IID_IUnknown, reinterpret_cast
(&pUnknown) ); if ( SUCCEEDED( hr ) ) { ConnectionPointHelper
cph( pUnknown ); LONG c = pCom->Add( 1, 5 ); } }

  CSink3的实现(与free2000fly写的一样):

// 要响应连接点事件,只需要重写此类// class DECLSPEC_UUID( "492194D9-7BEE-422D-AE7C-C43A809F20EC" ) CSink3;class ATL_NO_VTABLE CSink3	: public CSinkImpT < CSink3, ComDllLib::_ITestComEvent >{public:	CSink3( void ) {  }	virtual ~CSink3( void ) {}	typedef CSinkImpT
_parentClass; STDMETHOD( DoInvoke )(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr) { // 3. the dispidMember must referenced from .thl file, and you can have a look using oleview.exe switch ( dispidMember ) { case 1: { CComVariant result( *pvarResult ); if ( SUCCEEDED( result.ChangeType( VT_BSTR ) ) ) ::MessageBoxW( ::GetActiveWindow(), result.bstrVal, L"Sink Message", MB_OK ); return S_OK; } default: break; } return _parentClass::DoInvoke( dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr ); }};

  

转载于:https://www.cnblogs.com/honker/p/3773048.html

你可能感兴趣的文章
linux 给目录增加sgid权限
查看>>
POJ 1308 Is It A Tree?
查看>>
Scrapy常见问题(FAQ)
查看>>
java里int和Integer什么区别
查看>>
搜索常用到的“Do you mean"功能的算法(收藏)
查看>>
PHP安全方面的配置
查看>>
(转)如何选择 compileSdkVersion, minSdkVersion,targetSdk
查看>>
【win10系统】idea 修改Git密码和账号方法
查看>>
RandomAccessFile
查看>>
Mysql 不同条件进行修改存储
查看>>
百度地图给map添加右键菜单(判断是否为marker)
查看>>
线程的状态
查看>>
CentOS 6.4上通过yum安装Nagios-3.5.0 [服务端/server端]
查看>>
ODL Beryllium (Be) - The Fourth Release of OpenDaylight PRODUCTION-READY OPEN SDN PLATFORM
查看>>
Cortex-M0 ARM-GCC 编译链接选项
查看>>
JFinal中EhCache利用RMI方式分布式缓存配置
查看>>
谈传奇世界3D版
查看>>
我的友情链接
查看>>
【阿里云新品发布·周刊】第8期:数字化风暴已经来临!云+区块链,如何颠覆未来科技?...
查看>>
我的友情链接
查看>>