COM组件接收器实现(DLL、Custom)

 1     接收器接口工程的创建

接受器是一个微COM服务器,可以用ATL创建一个工程,添加接口函数,编译。保留其工程头文件“xxx.h”与接口ID即可。

       本例中创建了名为ISinkServer的工程和名为ISink的接口,为添加接口方法test2(long lArg)。

2     服务器的创建

       使用ATL创建名为RealServer的服务器(选择DLL),添加接口IReal(Apartment,Custom,Aggregation(Yes),Support Connection Points)。为接口添加方法test1(long lArg)。为_IRealEvents连接点添加回调方法test2(long lArg),并实现(Implement)其连接点。

       在工程目录下加入guids.h,其中包含接收器IID_ISink。并在工程cpp的前端#include"guids.h"。

       实现后的代码(RealServerCP.h)如下所示,修改完代码后便可在CReal中调用Fire_test2了。

#ifndef _REALSERVERCP_H_
#define _REALSERVERCP_H_
#include "..\SinkServer\SinkServer.h"
EXTERN_C const IID IID_ISink;
template <class T>
class CProxy_IRealEvents : public IConnectionPointImpl<T, &IID_ISink, CComDynamicUnkArray>
{
public:
	HRESULT Fire_test2(LONG lArg)
	{
   		T* pT = (T*)this;
		pT->Lock();
		HRESULT ret;
	         IUnknown** pp = m_vec.begin();
	         while (pp < m_vec.end())
	         {
		         if (*pp != NULL)
		         {
				ISink *pWzdSinks = reinterpret_cast<ISink*>(*pp);
				ret = pWzdSinks->test2( lArg );
		         }
			pp++;
		}
		pT->Unlock();
		return ret;
	}
};
#endif

3     客户端的创建

       使用MFC建立对话框应用程序Client,在对话框头文件前端包含接收器接口工程头文件#include "SinkServer\SinkServer.h"。

       并在消息定义宏下方添加:

DECLARE_INTERFACE_MAP()
BEGIN_INTERFACE_PART(SinkClass, ISink)
	STDMETHOD_(HRESULT,test2)(long);
END_INTERFACE_PART(SinkClass)

       在对话框cpp文件的消息定义宏下添加:

BEGIN_INTERFACE_MAP (CClientDlg, CClientDlg)
INTERFACE_PART (CClientDlg, IID_ISink, SinkClass)
END_INTERFACE_MAP ()

        完成接收器的几个基本函数与自定义函数:

ULONG FAR EXPORT CClientDlg::XSinkClass::AddRef()
{
	METHOD_PROLOGUE(CClientDlg, SinkClass);
	return pThis->ExternalAddRef();//pThis accesses enclosing class's this pointer
}
ULONG FAR EXPORT CClientDlg::XSinkClass::Release()
{
	METHOD_PROLOGUE(CClientDlg, SinkClass);
	return pThis->ExternalRelease();
}
HRESULT FAR EXPORT CClientDlg::XSinkClass::QueryInterface(REFIID iid, void FAR* FAR* ppvObj)
{
	METHOD_PROLOGUE(CClientDlg, SinkClass);
    return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}
HRESULT __stdcall CClientDlg::XSinkClass::test2(long lArg)
{
	METHOD_PROLOGUE(CClientDlg, SinkClass);
	CString str;
	str.Format("%d",lArg);
	AfxMessageBox(str);
    return S_OK;
}

       在对话框cpp文件的前端加入,其中guids.h为包含接收器IID头文件,IID_IReal和CLSID_Real从服务器RealServer获取:

#include "guids.h"
#include "RealServer/RealServer.h"
#include <afxctl.h>
const IID IID_IReal = {0xA8CA226A,0x69B1,0x4D10,{0x9A,0x25,0xD0,0x71,0x96,0x0B,0xD8,0x85}};
const CLSID CLSID_Real = {0xEA9E614F,0x5EBE,0x41ED,{0x9B,0x96,0xF7,0x6D,0x37,0xB1,0xEB,0x29}};

       接下来便可以在程序中进行接口调用了。

void CClientDlg::OnOK() 
{
	// TODO: Add extra validation here
	HRESULT hr;
	IReal *IMyReal = NULL;
	hr = CoInitialize(0);
	if (SUCCEEDED(hr))
	{
		//以下两段代码二选一
		/***************************/
		/*hr = CoCreateInstance(CLSID_Real,
			NULL,
			CLSCTX_INPROC_SERVER,
			IID_IReal,
			(void**)&IMyReal);*/
		/***************************/
		IClassFactory* pIFactory = NULL;    
		hr = CoGetClassObject(CLSID_Real,                        
			CLSCTX_INPROC_SERVER,                        
			NULL,                        
			IID_IClassFactory,                        
			(void**)&pIFactory);    
		if (SUCCEEDED(hr))    
		{        
			// create the component.        
			hr = pIFactory->CreateInstance(NULL, IID_IReal, (void**)&IMyReal);        
			pIFactory->Release();    
		}
		/****************************/
	}
	ISink *IMySink = NULL;
	hr = m_xSinkClass.QueryInterface(IID_ISink,(void**)&IMySink);
	m_xSinkClass.Release();
	DWORD dwConnectID;
	hr = AfxConnectionAdvise(
		IMyReal,			// the real server
		IID_ISink,		// our sink's IID
		IMySink,			// our sink's pointer
		FALSE,			// TRUE == increment our sink object's ref count
		&dwConnectID);		// identifier for AfxConnectionUnadvise()
	IMyReal->test1(1);
	AfxConnectionUnadvise(
		IMyReal,			// the real server
		IID_ISink,		// our sink's IID
		IMySink,			// our sink's pointer
		FALSE,			// TRUE == decrement our sink object's ref count
		dwConnectID);		// identifier from AfxConnectionAdvise()
	CoUninitialize();
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值