WEB开发网
开发学院软件开发VC COM 组件设计与应用(十六)——连接点(vc.net) 阅读

COM 组件设计与应用(十六)——连接点(vc.net)

 2006-07-22 22:55:30 来源:WEB开发网   
核心提示: 示例程序中的第2个组件(MultConnect),我们再增加一个连接点( _IDispConnectEvents2 ),COM 组件设计与应用(十六)——连接点(vc.net)(4),这个接口对象负责完成一个时钟,每间隔一定的豪秒就向调用者发出“时钟事件”,就是VT

示例程序中的第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 表示。示例程序中有对该类型的操作示范。

上一页  1 2 3 4 

Tags:COM 组件 设计

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接