COM 组件设计与应用(十六)——连接点(vc.net)
2006-07-22 22:55:30 来源:WEB开发网示例程序中的第2个组件(MultConnect),我们再增加一个连接点( _IDispConnectEvents2 )。这个接口对象负责完成一个时钟,每间隔一定的豪秒就向调用者发出“时钟事件”。增加第二个连接点的方法是要手工修改 IDL 文件
......
library MultConnectLib
{
importlib("stdole2.tlb");
...... // 第一个连接点。是 ATL 帮我们生成的
[ // 第2个连接点,需要我们手工添加
uuid(E3330AE1-2B1D-42E6-A8E0-A9CB0D1AC74C), // CLSID 可以用 GUIDGEN.EXE 产生
helpstring("_IDispConnect事件接口")
]
dispinterface _IDispConnectEvents2
{
properties:
methods:
};
[
uuid(4B0FDB44-BAF2-4F25-A2B0-B5ECD5CD440E), // 这是示例程序的类型库ID,肯定和你产生是不同的
helpstring("DispConnect Class")
]
coclass DispConnect
{
[default] interface IDispConnect;
[default, source] dispinterface _IDispConnectEvents;
[source] dispinterface _IDispConnectEvents2; // 别忘了,这还有一行
};
};
好了,和前面的方式一样,增加接口函数、让IDE帮我们实现代理类代码、输入程序代码、修改框架代码中的BUG。在示例中,我们的事件函数叫 HRESULT Timer([in] VARIANT varData),varData 中传递一个时间类型(VT_DATA)的信息(注3)。下面我们来看一下代理类代码中的错误:
HRESULT Fire_Timer( VARIANT varDate)
{
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();
IDispatch * pConnection = static_cast(punkConnection.p);
if (pConnection)
{
CComVariant avarParams[1];
// 原始为:avarParams[0] = varDate; avarParams[0].vt = VT_VARIANT;
// 但可惜这是错误的,因为 avarParams[0] = varDate; 就已经正确地完成了赋值
// 再对 avarParams[0].vt 赋值,是引用方式才能这么操作的。
avarParams[0] = varDate; // 这才是正确的操作
CComVariant varResult;
DISPPARAMS params = { avarParams, NULL, 1, 0 };
hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL);
}
}
return hr;
}
在编写调用者客户端代码方面,如果你需要接收时钟事件,那么可以仿照示例一再从 IDispatch 派生一个时钟接收器。大家下载事例程序代码,里面有丰富的注释信息。
六、小结
连接点,尤其是双接口的连接点,在远程(DCOM)环境上运行效率是比较低的。如果你只想完成简单的“通知”功能,那么前一回中的“回调接口”是一个明智的方案,并且可以运行在DCOM环境上。连接点方案当然也很重要,因为微软的许多应用程序(IE、Office......)都支持连接点,并且 ActiveX 只能通过连接点接口提供“事件”功能。所以,咱们还是都掌握为善吧。善哉 、善哉......
注1:金庸老先生的武侠小说里,总是用“XX 紧”来表示“很 XX”。我也学一学,嘿嘿。
注2:如果看了好几遍,您老人家还不会的话,那只好......先别学了。5555
注3:DATA 类型就是是8字节的double,它的整数部分表示从 1899年12月30日开始的总天数,小数部分表示当天的时间已经渡过了一天的多少分之一。这个时间类型,用VARIANT表示,就是VT_DATE类型,MFC 中用 COleDateTime 表示。示例程序中有对该类型的操作示范。
更多精彩
赞助商链接