Обработка событий ATL / ActiveX из JavaScript - PullRequest
2 голосов
/ 27 августа 2010

У меня есть элемент управления ATL ActiveX, который вызывает три события (Подключено, Аутентифицировано, Отключено), которые необходимо обработать в IE / JavaScript.Насколько я могу судить, я все делаю правильно, в частности:

(1) Я сказал ATL реализовать интерфейс IProviderClassInfo2, как описано здесь .

(2) Я реализовал точки подключения в своем проекте ATL, следуя указаниям здесь .Теперь у меня есть класс CProxy_IMyControlEvents с соответствующими реализациями Fire_Authenticated (), Fire_Connected () и Fire_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,  &params, &varResult, NULL, NULL);
   }
  }
  return hr;
 }
};

(3) Я вызываю Fire_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.Кажется, это то, где я сталкиваюсь с неприятностями.Я видел три разных способа сделать это, и ни один из них, похоже, не работает для меня.

<!-- Method #1 -->
<script language="javascript">
myControl.attachEvent('Connected', onConnected);
myControl.attachEvent('Disconnected', onDisconnected);
myControl.attachEvent('Authenticated', onAuthenticated);
</script>

<!-- Method #2 -->
<script language="javascript">
myControl.Connected = onConnected;
myControl.Disconnected = onDisconnected;
myControl.Authenticated = onAuthenticated;
</script>

<!-- Method #3 -->
<script for="MyControl" language="javascript">
function MyControl::Connected()
{
    onConnected();
}

function MyControl::Disconnected()
{
    onDisconnected();
}

function MyControl::Authenticated()
{
    onAuthenticated();
}
</script>

Я готов ко всему, что я могу найти в Интернете о том, как это сделатьи, похоже, я ничего не оставляю.Так что я должен делать что-то глупое.Любые предложения о том, что я могу делать неправильно или как это устранить?

Ответы [ 2 ]

3 голосов
/ 27 августа 2010

Я понял это, посмотрев пример проекта Circ, который поставляется с VS2010. Оказывается, что (по крайней мере, в моем случае) мастер событий ATL не обновил IDL для интерфейса диспетчеризации. Жизнь была хороша, как только я обновил раздел dispinterface файла IDL из этого:

dispinterface _IMyControlEvents
{
    properties:
    methods:
};

К этому:

dispinterface _IMyControlEvents
{
    properties:
    methods:
        [id(1)] void Connected();
        [id(2)] void Disconnected();
        [id(3)] void Authenticated();
};

Как только я это сделал, я смог заставить работать различные синтаксисы обработки событий.

0 голосов
/ 27 августа 2010

Во-первых, во всех примерах, которые я вижу из MSDN, в качестве языка используется «JScript», а не «javascript», но я не знаю, имеет ли это значение (возможно, оба приемлемы, но технически реализация ECMA в MS - это JScript Я верю).

В качестве варианта вашего метода 3, возможно, попробуйте указать в сценарии атрибут EVENT:

<script for="MyControl" EVENT="Connected()" language="JScript">
  onConnected();
</script>

<script for="MyControl" EVENT="Disconnected()" language="JScript">
  onDisconnected();
</script>

<script for="MyControl" EVENT="Authenticated()" language="JScript">
  onAuthenticated();
</script>
...