如何从C++;(ActiveX)到JavaScript 我遵循微软的教程,介绍如何实现C++的连接点和触发函数。问题是我无法使用正确的连接初始化IConnectionPointImpl::m_vec数组,因此m_vec.size=0
在.IDL文件中,我声明了以下接口:如何从C++;(ActiveX)到JavaScript 我遵循微软的教程,介绍如何实现C++的连接点和触发函数。问题是我无法使用正确的连接初始化IConnectionPointImpl::m_vec数组,因此m_vec.size=0,javascript,javascript-events,event-handling,activex,atl,Javascript,Javascript Events,Event Handling,Activex,Atl,在.IDL文件中,我声明了以下接口: [ uuid(F5219084-9D70-474A-8C05-46FFD1FCCC71), version(1.0), helpstring("BCPlayer 1.0 Type Library") ] library VPlayerLib { importlib("stdole2.tlb"); [ uuid(C4DFAB9A-435A-41A9-96B6-B23056DAA3FC),
[
uuid(F5219084-9D70-474A-8C05-46FFD1FCCC71),
version(1.0),
helpstring("BCPlayer 1.0 Type Library")
]
library VPlayerLib
{
importlib("stdole2.tlb");
[
uuid(C4DFAB9A-435A-41A9-96B6-B23056DAA3FC),
helpstring("_IVPlayerEvents Interface")
]
dispinterface _IVPlayerEvents
{
properties:
methods:
[id(1)] HRESULT OnInfoCallback([in] BSTR pPlayerName, [in] BOOL bSuccessMsg, [in] LONG nCode, [in] HRESULT hrRet);
};
...
...
稍后,使用Visual Studio的连接点向导创建了以下代理:
template<class T>
class CProxy_IVPlayerEvents :
public ATL::IConnectionPointImpl<T, &__uuidof(_IVPlayerEvents)>
{
public:
HRESULT Fire_OnInfoCallback(BSTR pPlayerName, BOOL bSuccessMsg, LONG nCode, HRESULT hrRet)
{
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 avarParams[4];
avarParams[3] = pPlayerName;
avarParams[3].vt = VT_BSTR;
avarParams[2] = bSuccessMsg;
avarParams[2].vt = VT_BOOL;
avarParams[1] = nCode;
avarParams[1].vt = VT_I4;
avarParams[0] = hrRet;
avarParams[0].vt = VT_HRESULT;
CComVariant varResult;
DISPPARAMS params = { avarParams, NULL, 4, 0 };
hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL);
}
}
return hr;
}
};
连接点地图:
BEGIN_CONNECTION_POINT_MAP(VPlayer)
CONNECTION_POINT_ENTRY(__uuidof(_IVPlayerEvents))
END_CONNECTION_POINT_MAP()
在javascript中,我尝试使用attachEvent和addEventListener进行绑定,而第一个尝试向m_vec添加了4个连接,但在销毁CComvaraint的过程中导致内存损坏:
avarParams[3] = pPlayerName;
avarParams[3].vt = VT_BSTR;
而addEventListener没有更改::m_vec并将其保持为零大小。在查看MSDN之后,我意识到addEventListener是绑定IE9及以上版本回调的首选方法
事件绑定的JavaScript代码:
function OnInfoCallback(){
var a = arguments[0];
var b = arguments[1];
var c = arguments[2];
var d = arguments[3];
alert("here");
}
...
...
player.addEventListener("OnInfoCallback", OnInfoCallback, false);
感谢您的帮助您找到了实现此功能的方法吗?事实上,我找到了,我没有使用任何连接点,只是创建了一个setter函数,该函数接收IDispatch*并将其存储到一个CComPtr中,然后使用InvokeN()调用回调。
avarParams[3] = pPlayerName;
avarParams[3].vt = VT_BSTR;
function OnInfoCallback(){
var a = arguments[0];
var b = arguments[1];
var c = arguments[2];
var d = arguments[3];
alert("here");
}
...
...
player.addEventListener("OnInfoCallback", OnInfoCallback, false);