none
在VB6中如何调用含有连接点的COM组件,实现对该连接点事件的响应? RRS feed

  • 问题

  •  

    问题概述:

     

         我通过VC ATL 开发了一个COM组件,里面包含一个连接点,代码在下面,我在VB6中

    试图通过 WithEvents 来响应该连接点的事件,结果发现没有响应,哪位大侠能帮我解决这个问题?

    也不知道是VC代码中有问题还是VB6代码中的问题

     

    详细描述:

     

      我在VC中做了一个ATL组件,名为CConnector ,主体关键代码如下:

    // CConnector

    class ATL_NO_VTABLE CConnector :
     public CComObjectRootEx<CComSingleThreadModel>,
     public CComCoClass<CConnector, &CLSID_Connector>,
     public IConnectionPointContainerImpl<CConnector>,
     public CProxy_IConnectorEvents<CConnector>,
     public IDispatchImpl<IConnector, &IID_IConnector, &LIBID_DispConnectLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
    {
    public:
          ....

    BEGIN_CONNECTION_POINT_MAP(CConnector)
     CONNECTION_POINT_ENTRY(__uuidof(_IConnectorEvents))
    END_CONNECTION_POINT_MAP()


     ...

    public:

     STDMETHOD(add)(LONG var1, LONG var2);
    };

     

    //其中CProxy_IConnectorEvents<CConnector>是对IDL中 _IConnectorEvents接口的代理,接口定义如下:

     dispinterface _IConnectorEvents
     {
      properties:
      methods:
       [id(1), helpstring("method Update")] HRESULT Update(void);
     };

     

    // add 方法的实现如下:

    STDMETHODIMP CConnector::add(LONG var1, LONG var2)
    {
     AFX_MANAGE_STATE(AfxGetStaticModuleState());

     // TODO: Add your implementation code here
     this->Fire_Update();

     return S_OK;
    }

     

     

     

    我在VB6中是这样调用的:

     


    '在VB中在定义对象,该COM组件是通过VC ATL 开发的,并且定义了一个
    '连接点,触发事件的方法是add,事件发出是Update,详细见VC程序
    Public m_connector As DispConnectLib.Connector

    '定义事件的响应,把连接点事件定义引入到VB程序中
    Public WithEvents AppEvent As DispConnectLib.Connector


    '事件响应的实现
    Private Sub AppEvent_Update()
        MsgBox "ok"
    End Sub


    '事件触发
    Private Sub Command2_Click()
        '通过COM对象的接口方法来触发事件,详细见VC程序
         m_connector.Add 1, 2
    End Sub

    Private Sub Form_Load()

        ' 生成COM对象的实例
        Set m_connector = New DispConnectLib.Connector
     
    End Sub

     

    调试过程中,我发现在VB6中调用了m_connector.Add 1, 2后,VC程序的确进入到了

    STDMETHODIMP CConnector::add(LONG var1, LONG var2)
    {
     AFX_MANAGE_STATE(AfxGetStaticModuleState());

     // TODO: Add your implementation code here
     this->Fire_Update();

     return S_OK;
    }

    this->Fire_Update();的确被调用,但是跟踪进入到Fire_Update()中,

     


    template<class T>
    class CProxy_IConnectorEvents :
     public IConnectionPointImpl<T, &__uuidof(_IConnectorEvents)>
    {
    public:
     HRESULT Fire_Update()
     {
      HRESULT hr = S_OK;
      T * pThis = static_cast<T *>(this);
      int cConnections = m_vec.GetSize();

      for (int iConnection = 0; iConnection < cConnections; iConnection++)
      {
       pThis->Lock();
       CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
       pThis->Unlock();

       IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);

       if (pConnection)
       {
        CComVariant varResult;

        DISPPARAMS params = { NULL, NULL, 0, 0 };
        hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, &varResult, NULL, NULL);
       }
      }
      return hr;
     }
    };

     

    发现  int cConnections = m_vec.GetSize(); 后 cConnections  = 0;

    所有实际上,COM对象的连接点并没有与任何对象发生连接,所以在VB中

    Public WithEvents AppEvent As DispConnectLib.Connector 语句

    并没有实际性的建立COM对象的连接点以相应事件。

     

    但是在VB6中怎么才能利用COM组件的连接点呢?谁能给答复,非常感谢!

     

     


     

    2008年7月3日 9:35

答案

全部回复