您的位置:首页 > 其它

IDL中提供的[source]属性,是为了让实现类宣扬它支持哪几个对外接口注册。

2008-02-02 08:21 323 查看
IDL中提供的[source]属性,是为了让实现类宣扬它支持哪几个对外接口注册。



主要表达的意思的是--组件内部在某种条件下将调用该接口,向外界传递信息。如果你对此信息感兴趣,就要自己实现这个接口,并向该组件注册并连接。这样当组件调用该接口时,会向你及时传递你感兴趣的信息。

例如:

coclass Math
{
[default] interface IMath;
[source, default] dispinterface _IMathEvents; <==== 对外宣扬 Math组件支持_IMathEvents对外接口的注册。
};

com包括引入接口和引出接口,来描述组件可以支持的两种不同类型的接口。
. 一个引入接口是指由组件实现的接口,这里的IMath接口就是一个引入接口。因为它是有组件来实现的。

.一个引出接口是指在组件的类型库中描述的接口,这里的_IMathEvents接口就是一个引入接口。它实际上是由Math组件的客户机来实现的。

下面展示_IMathEvents接口是如何实现,并与组件Math组件注册并链接的。

========================_IMathEvents接口的实现==========================
class CMathEvents :
public CComObjectRoot,
public _IMathEvents
{
public:
CMathEvents()
{
}
BEGIN_COM_MAP(CMathEvents)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(_IMathEvents)
END_COM_MAP()
// IMathEvents
public:
STDMETHODIMP GetTypeInfoCount(UINT*)
{
return E_NOTIMPL;
}
STDMETHODIMP GetTypeInfo( UINT iTInfo,
LCID lcid,
ITypeInfo **ppTInfo)
{
return E_NOTIMPL;
}
STDMETHODIMP GetIDsOfNames( REFIID riid,
LPOLESTR *rgszNames,
UINT cNames,
LCID lcid,
DISPID *rgDispId)
{
return E_NOTIMPL;
}
STDMETHODIMP Invoke( DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS *pDispParams,
VARIANT *pVarResult,
EXCEPINFO *pExcepInfo,
UINT *puArgErr)
{
switch( dispIdMember )
{
case 0x1:
// Make sure the is just one argument
if ( pDispParams->cArgs != 1 )
return DISP_E_BADPARAMCOUNT;
// We don't support named arguments
if ( pDispParams->cNamedArgs )
return DISP_E_NONAMEDARGS;
// Coerce the argument into a long
HRESULT hr;
VARIANTARG var;
VariantInit( &var );
hr = VariantChangeTypeEx( &var,
&(pDispParams->rgvarg[0]),
lcid, 0, VT_I4 );
if FAILED( hr )
return DISP_E_BADVARTYPE;
ComputationComplete( var.lVal );
break;
default:
DisplayMessage( "Error" );
break;
}
return S_OK;
}

STDMETHODIMP ComputationComplete(long lResult)
{
char szMsg[128];
sprintf( szMsg, "The result is %d", lResult );
DisplayMessage( szMsg );
return S_OK;
}
};

=========================与Math组件注册并链接============================
CComPtr<IMath> ptrMath;
HRESULT hr;
hr = CoCreateInstance( CLSID_Math, <==== 创建宣扬支持_IMathEvents对外接口的组件
NULL,
CLSCTX_SERVER,
IID_IMath,
(void**) &ptrMath );

if ( FAILED( hr ))
{
HandleError( "Failed to create server instance", hr );
return -1;
}

CComObject<CMathEvents>* ptrMathEvents;
CComObject<CMathEvents>::CreateInstance( &ptrMathEvents ); <======= 创建实现_IMathEvents的组件实例

CComPtr<IUnknown> ptrEventsUnk = ptrMathEvents;
//
IMathEvents *pMathEvents;
hr = ptrMathEvents->QueryInterface(IID_IMathEvents, (void **)&pMathEvents); <=======获得_IMathEvents接口指针

// Set up the connection
DWORD dwCookie;
hr = AtlAdvise( ptrMath,
pMathEvents,
DIID__IMathEvents,
&dwCookie ); <======将_IMathEvents接口指针pMathEvents在ptrMath组件实例中注册并链接
if (FAILED( hr ))
{
HandleError( "Unable to setup the connection for IMathEvents", hr );
return -1;
}

// Access the IMath interface
long lResult;
ptrMath->Add( 300, 10, &lResult ); <========调用ptrMath组件方法。组件方法执行过程中会适时通过传入的_IMathEvents接口指针pMathEvents向调用者返回信息--回调。
ptrMath->Subtract( 300, 10, &lResult );
ptrMath->Multiply( 300, 10, &lResult );
ptrMath->Divide( 300, 10, &lResult );

// Shut down the event connection
AtlUnadvise( ptrMath,
DIID__IMathEvents,
dwCookie ); <======中断_IMathEvents接口指针与ptrMath组件实例的链接

.....

其中AtlAdvise和AtlUnadvise的实现过程是这样的:

CComPtr<IUnknown>
spSource = /* Set to the source of the events */ ;
CComPtr<_ISpeakerEvents>
spSink = /* Sink to receive the events */ ;
DWORD dwCookie ;

CComPtr<IConnectionPointContainer> spcpc;
HRESULT hr = spSource.QueryInterface (&spcpc);

CComPtr<IConnectionPoint> spcp ;
hr = spcpc->FindConnectionPoint(__uuidof(_ISpeakerEvents),
&spcp); <======根据_ISpeakerEvents来查找ConnectionPoint。只有组件宣扬的对外接口,才可以查找成功。
hr = spcp->Advise (spSink, &dwCookie) ; // Establish connection
// Time goes by, callbacks occur...
hr = spcp->Unadvise (dwCookie) ; // Break connection

hr = AtlAdvise( ptrMath, // 对外宣扬 支持_IMathEvents接口
pMathEvents, // _IMathEvents类型接口指针
DIID__IMathEvents,
&dwCookie );

结论:对于AtlAdvise,只有组件宣扬的对外接口,才可以注册成功。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐