博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
COM Tip(2)
阅读量:5305 次
发布时间:2019-06-14

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

 

一.使用IDispatch

interface IRandom : IDispatch{    import "oaidl.idl";    [id(0)]    HRESULT Start([out]long* pnID);    [id(1)]    HRESULT Stop([in]long nID);    [id(2)]    HRESULT StopAll();};

使用GetIDsOfNames获取DISP

OLECHAR *fn=L"Stop";DISPID id;pRandom->GetIDsOfNames(IID_NULL,&fn,1,GetUserDefaultLCID(),&id);

使用Invoke动态调用函数

VARIANT var;::VariantInit(&var);var.lVal=2;DISPPARAMS params;params.cArgs=1;params.rgvarg=&var;pRandom->Invoke(id,IID_NULL,GetUserDefaultLCID(),DISPATCH_METHOD,    &params,NULL,NULL,NULL);

跟反射的概念完全是一样的

二.IDispatchImpl

ATL中,IDispatchImpl实现了IDispatch

class CRandom :    public IDispatchImpl
,{public: CRandom() { } ~CRandom();BEGIN_COM_MAP(CRandom) COM_INTERFACE_ENTRY2(IDispatch, IRandom) COM_INTERFACE_ENTRY(IRandom)END_COM_MAP() }

三.实现连接点

1.实现IConnectionPointContainerImpl和IConnectionPointImpl

class CRandom :    public IConnectionPointContainerImpl
, public IConnectionPointImpl

2.在客户端调用方实现IRandomEvent接口(接收器)

class CDriver :    public IDispatchImpl
, public CComObjectRoot{public: CDriver() {}BEGIN_COM_MAP(CDriver) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(IRandomEvent)END_COM_MAP()// IRandomEvent STDMETHOD(Fire)(long l);public:};

3.客户端创建连接点进行监听

CComObject
* pDriver;CComObject
::CreateInstance(&pDriver);pDriver->m_nID = m_nAdviseCnt;HRESULT hRes = AtlAdvise(pRandom, pDriver->GetUnknown(), IID_IRandomEvent, &m_arrAdvise[m_nAdviseCnt++]);

4.服务器端进行回调

IConnectionPointImpl
* p = this;Lock();HRESULT hr = S_OK;IUnknown** pp = p->m_vec.begin();while (pp < p->m_vec.end() && hr == S_OK){ if (*pp != NULL) { IRandomEvent* pIRandomEvent = (IRandomEvent*)*pp; hr = pIRandomEvent->Fire(nID); } pp++;}

5.自动生成连接点代理

第4步可以用vs自动生成代码,如果事件很多(而且客户端可以多次监听),写这些重复的代码是没有必要的

template
class CProxyIRandomEvent : public ATL::IConnectionPointImpl
{public: HRESULT Fire_Fire(long nID) { HRESULT hr = S_OK; T * pThis = static_cast
(this); int cConnections = m_vec.GetSize(); for (int iConnection = 0; iConnection < cConnections; iConnection++) { pThis->Lock(); CComPtr
punkConnection = m_vec.GetAt(iConnection); pThis->Unlock(); IRandomEvent * pConnection = static_cast
(punkConnection.p); if (pConnection) { hr = pConnection->Fire(nID); } } return hr; }};

 

class CRandom :    public IDispatchImpl
, public IConnectionPointContainerImpl
, public CProxyIRandomEvent
{public: CRandom() { } ~CRandom();// Connection Point1 BEGIN_CONNECTION_POINT_MAP(CRandom) CONNECTION_POINT_ENTRY(__uuidof(IRandomEvent)) END_CONNECTION_POINT_MAP()

让CRandom 继承自CProxyIRandomEvent,去掉之前的IConnectionPointImpl

转载于:https://www.cnblogs.com/Clingingboy/archive/2011/06/12/2078846.html

你可能感兴趣的文章
FZU2216【二分】
查看>>
[HNOI2008]Cards
查看>>
拖拉记录上下移动--Ajax UI
查看>>
摄像头标定
查看>>
[SOF] Pointers, smart pointers or shared pointers?
查看>>
I/O-<File区别>
查看>>
cf249D
查看>>
java.util.concurrent.ExecutionException
查看>>
团队项目(一)
查看>>
centos7安装zabbix3.0超详细步骤解析
查看>>
后台数据传值得到数字需转为汉字
查看>>
库的简介和分类
查看>>
雪碧图
查看>>
洛谷P1803
查看>>
康拓展开-排列的hash
查看>>
.Net实现微信公众平台开发接口(二) 之 “获取access_token”
查看>>
php命名空间
查看>>
idea创建spring-boot项目
查看>>
poj2155Matrix【二位树状数组】
查看>>
beta冲刺(4/7)
查看>>