ATL 开发 Com 学习笔记
Com 学习笔记
1. 数组数据类型(SAFEARRAY,VARIANT)
A、 返回JS数组。
//测试JS,C#等应用中返回数组值。
STDMETHODIMP CTestCall::GetArray(VARIANT* arrays)
{
// TODO: 在此添加实现代码
//返回数组
SAFEARRAY * psa;
//数组维数
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,
¶ms, &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,
¶ms, &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;
}