我遵循微软的教程,介绍如何实现连接点,并假设从C ++触发函数。问题是我无法通过适当的连接来初始化IConnectionPointImpl :: m_vec数组,因此,m_vec.size = 0.
在我的.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),
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;
}
};
在我的ATL对象中添加了以下继承:
, public IConnectionPointContainerImpl<VPlayer>
, public CProxy_IVPlayerEvents<VPlayer>
, public IProvideClassInfo2Impl<&__uuidof(VPlayer), &__uuidof(_IVPlayerEvents), &LIBID_VPlayerLib>
映射:
COM_INTERFACE_ENTRY(IConnectionPointContainer)
COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
END_COM_MAP()
连接点地图:
BEGIN_CONNECTION_POINT_MAP(VPlayer)
CONNECTION_POINT_ENTRY(__uuidof(_IVPlayerEvents))
END_CONNECTION_POINT_MAP()
在javascript中,我尝试使用attachEvent和addEventListener绑定,而第一个添加了4个连接到m_vec,但在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);
感谢您的帮助