我有一个ATL ActiveX控件,它会引发三个事件(已连接、已验证、已断开连接),这些事件需要在IE/JavaScript中处理。据我所知,我做的一切都是对的,特别是:
(1) 我已经告诉ATL实现IProviderClassInfo 2接口,如前所述
here
.
here
. 我现在有了一个CProxy\u IMyControlEvents类,它具有适当的Fire\u Authenticated()、Fire\u Connected()和Fire\u Disconnected()实现。它们看起来或多或少是这样的:
template<class T>
class CProxy_IVncServerControlEvents :
public ATL::IConnectionPointImpl<T, &__uuidof(_IVncServerControlEvents)>
{
public:
HRESULT Fire_Connected()
{
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 varResult;
DISPPARAMS params = { NULL, NULL, 0, 0 };
hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL);
}
}
return hr;
}
};
(3) 我在代码的适当位置(在主UI线程上)调用Fire\u Connected()等,调试器确认它们正在启动。
(4) 我在一个HTML页面中实例化生成的控件,并且能够对其调用方法。这些方法执行了它们应该执行的操作并成功返回。
<object id="MyControl" classid="CLSID:42832F4C-3480-4450-A6B5-156B2EFC408F" codebase="http://localhost:51150/Resources/MyControlInstaller.CAB" />
<script language="javascript">
var myControl = document.getElementById("MyControl");
myControl.connect();
</script>
(5) 我正在将事件连接到JavaScript函数处理程序。这似乎是我遇到麻烦的地方。我见过三种不同的方法,但似乎都不适合我。
<script language="javascript">
myControl.attachEvent('Connected', onConnected);
myControl.attachEvent('Disconnected', onDisconnected);
myControl.attachEvent('Authenticated', onAuthenticated);
</script>
<script language="javascript">
myControl.Connected = onConnected;
myControl.Disconnected = onDisconnected;
myControl.Authenticated = onAuthenticated;
</script>
<script for="MyControl" language="javascript">
function MyControl::Connected()
{
onConnected();
}
function MyControl::Disconnected()
{
onDisconnected();
}
function MyControl::Authenticated()
{
onAuthenticated();
}
</script>