在第六章的最后,
CTestDlg::OnSetproperty()
里面调用了driver.SetProperty(0x1,VT_I4,m_property);
这个函数的作用是什么?各个参数是什么,怎么用?它会调用IDispatch::Invoke()
它们是什么关系啊?谢谢

解决方案 »

  1.   

    在源对象的odl文件中设置了时间的id为0
    那么,这个SetProperty(0x1,VT_I4,m_property); 的第一个参数又代表什么呢?跟这个0有关系么
      

  2.   

    没看此书,此函数会调用IDispatch::Invoke() 
    就是调用服务端dispId为0x1,参数数据类型为VT_I4的方法或属性
      

  3.   

    服务端dispId为0x1?是什么东西啊?这本书没有提到这个,能和我讲一下吗?
    是不是调用了下面红色这个属性,只在这段代码中有,其他文件里没有出现MyProperty,不知道这个是用来干什么的
    [ uuid(B77C2984-56DD-11CF-B355-00104B08CC22) ]
    dispinterface ISourceObj
    {
    properties:
    // NOTE - ClassWizard will maintain property information here.
    //    Use extreme caution when editing this section.
    //{{AFX_ODL_PROP(CSourceObj)
    [id(1)] long MyProperty; //}}AFX_ODL_PROP

    methods:
    // NOTE - ClassWizard will maintain method information here.
    //    Use extreme caution when editing this section.
    //{{AFX_ODL_METHOD(CSourceObj)
    //}}AFX_ODL_METHOD };
      

  4.   

    SetProperty(0x1,VT_I4,m_property);第一个参数0x1,就是你红字部分标明的变量在组件内部的ID;也就是这个部分"[id(1)]";第二个你肯定知道了,是指的后面m_property的数据类型,VT_I4是一个4字节的数据,可能是LONG或者unsigned long等类型。SetProperty(0x1,VT_I4,m_property);这一句一般出现在控件当中形如SetMyProperty();这个接口函数形成的.cpp文件当中。例如你的Dlg引用了一个IsourceObj控件,添加这个控件的时候,会跟随生成.h和.cpp文件,
    cpp文件当中的就会有一个:
    SetMyProperty(LONG m_property)
    {
    }
      

  5.   

    没有回完就点了个回车 郁闷
    SetMyProperty(LONG m_property) 

        SetProperty(0x1,VT_I4,m_property);
    }
    如果参数很多就变成这个样子了:
    void CClock::SetKht(float x, long y, double z, DATE c, unsigned long e, const VARIANT& g, float newValue)
    {
        static BYTE parms[] = VTS_R4 VTS_I4 VTS_R8 VTS_DATE VTS_I4 VTS_VARIANT VTS_R4;
        InvokeHelper(0x5, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, x, y, z, c, e, &g, newValue);
    }
      

  6.   

    谢谢Tinary3v0哦~我再仔细想想。理理整个通信过程
      

  7.   

    还有几点没明白。我理解整个通信过程是这样:1.客户获得源对象的接口指针,然后得到源对象的连接点容器接口指针,接着找到连接点接口指针pConnPt2.然后pConnPt调用Advise()与客户端连接。连接成功了以后,在客户端调用了
    driver.SetProperty(0x1,VT_I4,m_property); 
    该函数又调用了下面的Invoke函数。
    STDMETHODIMP CTestCtrlDlg::XEventSink::Invoke(
    DISPID dispid, REFIID, LCID, unsigned short wFlags,
    DISPPARAMS* pDispParams, VARIANT* pvarResult,
    EXCEPINFO* pExcepInfo, unsigned int* puArgError)
    {
    if (dispid == 0) {//这里dispid是怎么的来的?SetProperty并没有传这个值呀?
    AfxMessageBox("The Property has been changed!");
    } else {
    AfxMessageBox("I don't known the event!");
    }
    return S_OK;
    }
    在源对象的odl文件里定义了接口IEventSet,并声明了id=0的函数。
    [id(0)] void PropChanged(long nInt);在源对象里实现了FirePropChanged,它里面也调用了InvokeHelper。
    void CSourceObj::FirePropChanged (long nInt)
    {
    COleDispatchDriver driver; POSITION pos = m_xEventSetConnPt.GetStartPosition();
    LPDISPATCH pDispatch;
    while (pos != NULL)
    {
    pDispatch = (LPDISPATCH) m_xEventSetConnPt.GetNextConnection(pos);
    ASSERT(pDispatch != NULL);
    driver.AttachDispatch(pDispatch, FALSE);
    TRY
    driver.InvokeHelper(0, DISPATCH_METHOD, VT_EMPTY, NULL, (BYTE *)(VTS_I4), nInt);
    END_TRY
    driver.DetachDispatch();
    }
    }我搞不懂了。在这里odl里定义了一个方法和一个属性。但是并找不到它们有在什么地方被用到啊。
    这个客户端和原对象的通信过程完整的到底是怎么样的呢?我给帖子加分。希望大家多帮帮我。谢谢
      

  8.   

    主要是通信过程不明白。Invoke和InvokeHelper的作用没看明白。
      

  9.   

    事件最终会调用IDispatch::Invoke函数,所以InvokeHelper仅仅是对Invoke的一个包装,用来按照类型转换成合适的参数。