ATL 开发 Com 学习笔记

Com 学习笔记

1.       数组数据类型(SAFEARRAYVARIANT

A、 返回JS数组。

//测试JS,C#等应用中返回数组值。

STDMETHODIMP CTestCall::GetArray(VARIANT* arrays)

{

    

     // TODO: 在此添加实现代码

     //返回数组

     SAFEARRAYpsa;

     //数组维数

     SAFEARRAYBOUND rgsabound[1];

 

     rgsabound[0].lLbound = 0;

     rgsabound[0].cElements = 2;

     psa=SafeArrayCreate(VT_VARIANT,1,rgsabound);//我这里原来没用VT_VARIANT,而是用了VT_I4类型,结果会导致JS代码中new VBArray出错,请一定注意

 

 

     LONG index;

     //赋值方法1

     CComVariant setdt(4,VT_I4);

     index = 0;

     SafeArrayPutElement(psa,&index,&setdt);

     index=1;

     setdt = 2;

     SafeArrayPutElement(psa,&index,&setdt);

 

 

     //赋值方法2

     VARIANT* v;

     SafeArrayAccessData(psa,(void HUGEP **) &v);

     setdt=1;

     v[0] = setdt;

     setdt = 7;

     v[1] = setdt;

     SafeArrayUnaccessData(psa);

 

     //返回安全数组

     CComVariant rhArray(psa);

     ::VariantInit(arrays);

     arrays->vt = VT_EMPTY;

     rhArray.Detach(arrays);

     //V_VT(arrays) = VT_ARRAY | VT_VARIANT;

     //V_ARRAY(arrays) = psa;   

     return S_OK;

}

B测试应用程调用传入数组值。

STDMETHODIMP CTestCall::SetSafeArray(SAFEARRAY * safeArry)

{

     // TODO: 在此添加实现代码

     //this->safeArray = safeArray;

     LONG *v;

     SafeArrayAccessData(safeArry ,(void HUGEP **) &v);

     v[0] = 100;

     SafeArrayUnaccessData(safeArry);

     ::SafeArrayCopy((LPSAFEARRAY)safeArry, &this->safeArray);

     return S_OK;

}

C测试js脚本传入对象。

STDMETHODIMP CTestCall::SetJSArray(VARIANT jsArray)

{

     // TODO: 在此添加实现代码

     if(jsArray.vt != VT_DISPATCH)

         return DISP_E_TYPEMISMATCH;

     CComVariant result;

     CComPtr<IDispatch> js(jsArray.pdispVal);

     js.GetPropertyByName(OLESTR("length"),&result);

     js.GetPropertyByName(OLESTR("1"),&result); //这里代表 var jsArray = new Array();数组的序号。

     return S_OK;

}

2、伪异步测试

//Com 中的线程

void ThreadFN(void * p )

{

    CoInitialize(0);

    CComPtr<IDispatch> spCallback;

    threadParams * params2;

    params2 = (threadParams * )p;

    HRESULT hr = CoGetInterfaceAndReleaseStream(params2->istream,IID_NULL,(void **)&spCallback); //取出列集

    if(SUCCEEDED(hr))

    {

        // 参数准备

        CComVariant varResult;

        CComVariant avarParams[3];

        avarParams[0] = "开始计算股票";        // bstrProgressName

        avarParams[0].vt = VT_BSTR;

        avarParams[1] = 100;                              // nTotalProgress

        avarParams[1].vt = VT_I4;

        avarParams[2] = 0;                                 // nCurrentProgress

        avarParams[2].vt = VT_I4;

        DISPPARAMS params = { avarParams, NULL, 3, 0 };

 

        // DOUBLE v1 = 100;

        // DOUBLE v2 = 200;

        if(spCallback)

             spCallback->Invoke(0,

             IID_NULL,

             LOCALE_USER_DEFAULT,

             DISPATCH_METHOD,

             &params, &varResult, NULL, NULL);

 

        BOOL bFinished = false;

 

        int i=0;

        while(!bFinished)

        {

             // 计算工作…

             Sleep(1000);

             params2->v1 = params2->v1+params2->v2;

 

             // 回调客户

             if(spCallback)

             {

                  avarParams[0] = "正在计算股票";

                  avarParams[2] = i;

                  spCallback->Invoke(0,

                      IID_NULL,

                      LOCALE_USER_DEFAULT,

                      DISPATCH_METHOD,

                      &params, &varResult, NULL, NULL);

             }

 

             if(i == 10)

                  bFinished = TRUE;

             i = i+1;

        } // while OK!

    }

   

 

    delete(p);

    CoUninitialize();

}

 

 

STDMETHODIMP CjsCom::mycallback(DOUBLE v1, DOUBLE v2, VARIANT scriptCallback)

{

    // TODO: 在此添加实现代码

    CComPtr<IDispatch> spCallback;

 

    if (scriptCallback.vt == VT_DISPATCH)

        spCallback = scriptCallback.pdispVal;

 

 

    IStream * istream;

    HRESULT hr = CoMarshalInterThreadInterfaceInStream(IID_NULL,spCallback,&istream);//手动列集

    if(SUCCEEDED(hr))

    {

        threadParams *params = new threadParams;

        params->v1 = v1;

        params->v2 = v2;

        params->istream = istream;

        _beginthread(ThreadFN, 0,(void *)params );

    }

 

    return S_OK;

}

posted @ 2009-07-02 14:12  吴碧宇  阅读(891)  评论(0编辑  收藏  举报