Вопрос

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

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

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

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

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

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

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

Спасибо.

Это было полезно?

Решение

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

<script for="MyControl" event="ReceiveMessage(msg)">
    alert(msg);
</script>

Другие советы

Я уже использовал 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);
}

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

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

Он использовал "расширение" сложным образом из-за выбранного им примера, но если вы сделаете это простым, прикрепив дескриптор непосредственно к самому событию, это также сработает.C # ActiveX должен поддерживать "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 и другие элементы безопасности, чтобы заставить его работать лучше.

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

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

Я обнаружил, что этот код работает в теге формы.В этом примере 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>

В моем случае мне нужен был способ динамического создания элементов управления 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().

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top