Как обрабатывать событие ActiveX в Javascript - PullRequest
20 голосов
/ 30 сентября 2008

Это что-то вроде продолжения ответа здесь .

У меня есть пользовательский элемент управления ActiveX, который вызывает событие («ReceiveMessage» с параметром «msg»), которое должно обрабатываться Javascript в веб-браузере. Исторически нам удавалось использовать следующий синтаксис только для IE для выполнения этого в различных проектах:

function MyControl::ReceiveMessage(msg)
{
   alert(msg);
}

Однако, когда внутри макета, в котором скрыт элемент управления, Javascript не может найти элемент управления. В частности, если мы помещаем это в простую HTML-страницу, она работает нормально, но если мы помещаем это в страницу ASPX, обернутую тегом <Form>, мы получаем ошибку «MyControl is undefined». Мы пробовали варианты на следующем:

var GetControl = document.getElementById("MyControl");
function GetControl::ReceiveMessage(msg)
{
   alert(msg);
}

... но это приводит к ошибке Javascript «GetControl не определен».

Как правильно обрабатывать событие, отправляемое из элемента управления ActiveX? Сейчас мы заинтересованы только в том, чтобы это работало в IE. Это должен быть пользовательский элемент управления ActiveX для того, что мы делаем.

Спасибо.

Ответы [ 7 ]

13 голосов
/ 30 сентября 2008

Мне удалось заставить это работать, используя следующий формат блока скриптов, но мне все еще любопытно, является ли это лучшим способом:

<script for="MyControl" event="ReceiveMessage(msg)">
    alert(msg);
</script>
8 голосов
/ 08 июля 2010

Ранее я использовал activex в своих приложениях. я помещаю теги объектов в форму ASP.NET, и у меня работает следующий JavaScript.

function onEventHandler(arg1, arg2){
    // do something
}

window.onload = function(){
    var yourActiveXObject = document.getElementById('YourObjectTagID');
    if(typeof(yourActiveXObject) === 'undefined' || yourActiveXObject === null){
        alert('Unable to load ActiveX');
        return;
    }

    // attach events
    var status = yourActiveXObject.attachEvent('EventName', onEventHandler);
}
5 голосов
/ 19 декабря 2008

ОК, но если вы используете C # (.NET 2.0) с унаследованным UserControl (ActiveX) ... Единственный способ заставить его работать - это «расширить» функциональность обработчика события: http://www.codeproject.com/KB/dotnet/extend_events.aspx?display=Print

Приведенная выше ссылка на проект от нашего друга г-на Вернера Виллемсенса сохранила мой проект. Если вы этого не сделаете, javascript не сможет привязаться к обработчику событий.

Он использовал «расширение» сложным образом из-за выбранного им примера, но если вы упростили его, прикрепив дескриптор непосредственно к самому событию, это также работает. ActiveX C # должен поддерживать «ScriptCallbackObject» для привязки события к функции JavaScript, как показано ниже:

  var clock = new ActiveXObject("Clocks.clock");
  var extendedClockEvents = clock.ExtendedClockEvents();
  // Here you assign (subscribe to) your callback method!
  extendedClockEvents.ScriptCallbackObject = clock_Callback; 
  ...
  function clock_Callback(time)
  {
    document.getElementById("text_tag").innerHTML = time;
  }

Конечно, вы должны реализовать IObjectSafety и другие средства безопасности, чтобы он работал лучше.

1 голос
/ 11 мая 2012

В моем случае мне нужен был способ динамического создания элементов управления ActiveX и прослушивания их событий. Я смог заставить что-то вроде этого работать:

//create the ActiveX
var ax = $("<object></object>", {
    classid: "clsid:" + clsid,
    codebase: install ? cabfile : undefined,
    width: 0,
    height: 0,
    id: '__ax_'+idIncrement++
})
.appendTo('#someHost');

А затем зарегистрировать обработчик для события:

//this function registers an event listener for an ActiveX object (obviously for IE only)
//the this argument for the handler is the ActiveX object.
function registerAXEvent(control, name, handler) {
    control = jQuery(control);

    //can't use closures through the string due to the parameter renaming done by the JavaScript compressor
    //can't use jQuery.data() on ActiveX objects because it uses expando properties

    var id = control[0].id;

    var axe = registerAXEvent.axevents = registerAXEvent.axevents || {};
    axe[id] = axe[id] || {};
    axe[id][name] = handler;

    var script =
    "(function(){"+
    "var f=registerAXEvent.axevents['" + id + "']['" + name + "'],e=jQuery('#" + id + "');"+
    "function document." + id + "::" + name + "(){"+
        "f.apply(e,arguments);"+
    "}"+
    "})();";
    eval(script);
}

Этот код позволяет использовать замыкания и минимизирует область действия eval ().

Элемент <object> элемента управления ActiveX уже должен быть добавлен в документ; в противном случае IE не найдет элемент, и вы просто получите ошибки скрипта.

1 голос
/ 09 января 2009

Я обнаружил, что этот код работает в теге формы. В этом примере callback - это параметр функции, передаваемый javascript в элемент управления ActiveX, а callbackparam - параметр события обратного вызова, созданного в элементе управления ActiveX. Таким образом, я использую один и тот же обработчик событий для любых типов событий, а не пытаюсь объявить несколько отдельных обработчиков событий.

<object id="ActivexObject" name="ActivexObject" classid="clsid:15C5A3F3-F8F7-4d5e-B87E-5084CC98A25A"></object>

<script>
function document.ActivexObject::OnCallback(callback, callbackparam){
callback(callbackparam);
}
</script>

1 голос
/ 12 ноября 2008

Если на вашей странице есть элемент ActiveX с идентификатором «MyControl», то синтаксис вашего обработчика javascript следующий:

function MyControl::ReceiveMessage(msg)
{
   alert(msg);
}
0 голосов
/ 07 октября 2008

Я думаю, что пример MyControl :: ReceiveMessage не работает, поскольку элемент управления ActiveX предоставляется с другим именем или в другой области действия.

На примере GetControl :: ReceiveMessage я считаю, что определение функции анализируется до того, как устанавливается ссылка GetControl, поэтому оно не ссылается на действительный объект и не может связать функцию с объектом.

Я бы атаковал эту проблему, используя отладчик сценариев MS и пытаясь определить, существует ли ссылка по умолчанию для элемента управления с другим именем или в другой области (возможно, как дочерний элемент формы). Если вы можете определить правильную ссылку для элемента управления, вы сможете правильно связать функцию с помощью метода Automagic ::, который указан в статье MSDN.

Еще одна мысль, ссылка может основываться на имени объекта, а не на его ID, поэтому попробуйте установить оба:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...