atl异步线程调用js函数

来源:互联网 发布:c语言开方函数 编辑:程序博客网 时间:2024/05/24 15:43

问题:

atl组件内可能有另外线程事件需要通知到html页面,采用调用js回调的方法解决,比如voip呼入弹屏等功能

解决:

网上许多同步方法,即从js调用atl接口-》atl接口再调用js回调,我称之为同步方法

百度了许久,终于找到异步线程调用方法,整理记录如下:

1、js设置回调

<OBJECT id=wcall align="CENTER" WIDTH=0 HEIGHT=0 classid="CLSID:****"></OBJECT>

<script language="javascript">

function initVoip()

{

var ok = wcall.Open(ip,port,user,pwd);

alert(ok);

wcall.YqSetCBK(0,onCallIn);

wcall.YqSetCBK(1,onCalling);

wcall.YqSetCBK(2,onOnHook);

wcall.YqSetCBK(3,onTransError);

}

function onCallIn(callid,callst,phone)

{

alert('callin:'+phone+',callid:'+callid+',callstatus:'+callst);

}

function onCalling(callid)

{

alert('calling:'+callid);

}

function onOnHook(callid)

{

alert('onhook:'+callid);

}

function onTransError(callid)

{

alert('transError:'+callid);

}

</script>

2、atl设置回调接口函数实现

static HRESULT myCoMarshalInterThreadInterfaceInStream(

REFIID riid,

LPUNKNOWN pUnk,

LPSTREAM * ppStm)

{

HRESULT hres;

hres = CreateStreamOnHGlobal(NULL, TRUE, ppStm);

if (FAILED(hres)) return hres;

hres = CoMarshalInterface(*ppStm, riid, pUnk, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLESTRONG);

if (FAILED(hres))

{

(*ppStm)->Release();

*ppStm = NULL;

}

return hres;

}

STDMETHODIMP CCallInterface::YqSetCBK(LONG cbkType, VARIANT cbkJs)

{

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

if (cbkType < CMDCNT && cbkType >= 0 && cbkJs.vt == VT_DISPATCH){

CmdInterface[cbkType].cmdType = (CMDTYPE)cbkType;

if (CmdInterface[cbkType].cmdDispatch != NULL){

IDispatch *tmp= CmdInterface[cbkType].cmdDispatch;

CmdInterface[cbkType].cmdDispatch = NULL;

tmp->Release();

}

CmdInterface[cbkType].cmdDispatch = cbkJs.pdispVal;

CmdInterface[cbkType].cmdDispatch->AddRef();

if(FAILED(myCoMarshalInterThreadInterfaceInStream(IID_IDispatch,CmdInterface[cbkType].cmdDispatch,&CmdInterface[cbkType].cmdStream)))

{

CmdInterface[cbkType].cmdDispatch->Release();

CmdInterface[cbkType].cmdDispatch = NULL;

return S_FALSE;

}

return S_OK;

}

return S_FALSE;

}


3、呼入时,呼叫线程调用接口回调

IDispatch *getAsyncCmdDisp()

{

ULARGE_INTEGER xpos;

LARGE_INTEGER seekto;

IDispatch *pDisp;

HRESULT hr;

if (cmdType == CMD_NONE || cmdType == CMD_MAX)

return NULL;

if(CmdInterface[cmdType].cmdStream == NULL || CmdInterface[cmdType].cmdDispatch == NULL)

return NULL;

memset(&seekto,0,sizeof(seekto));

CmdInterface[cmdType].cmdStream->Seek(seekto,STREAM_SEEK_SET,&xpos);

hr = CoUnmarshalInterface(CmdInterface[cmdType].cmdStream,IID_IDispatch,(void**)&pDisp);

if(FAILED(hr)){

LogFile->WriteLog("CoUnmarshalInterface error");

return NULL;

}

return pDisp;


void Async_doCallIng()

{

IDispatch* pDisp = getAsyncCmdDisp();

if (pDisp){

//_com_dispatch_raw_method参数:L"\x0003\x0003\x0008"参看VALTYPE的值定义,后面类似printf的变参

_com_dispatch_raw_method(pDisp,0,DISPATCH_METHOD,VT_EMPTY,NULL,L"\x0003",callId);

pDisp->Release();

}

}

void Async_doCallIn()

{

IDispatch* pDisp = getAsyncCmdDisp();

if (pDisp){

_com_dispatch_raw_method(pDisp,0,DISPATCH_METHOD,VT_EMPTY,NULL,L"\x0003\x0003\x0008",callId,callStatus,CComBSTR(callPhone));

pDisp->Release();

}

}


4、确实可以弹框,哈哈

0 0
原创粉丝点击