2008-09-29 2 views
19

Это часть ответа на вопрос here.Как обрабатывать событие ActiveX в Javascript

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

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

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

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

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

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

Спасибо.

+0

Чтобы уточнить один момент - getElementById отлично работает. У нас есть ссылка на элемент управления, Javascript просто не любит нас, используя синтаксис :: с этой ссылкой. – Raelshark 2008-09-29 21:44:16

+0

Я никогда раньше не видел синтаксис :: где это документировано? – AnthonyWJones 2008-09-30 07:21:49

+0

Трудно найти документацию для него, но вот ссылка на статью MSDN, в которой упоминается: http://msdn.microsoft.com/en-us/library/ms974564.aspx – Raelshark 2008-09-30 11:57:44

ответ

12

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

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

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

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

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

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

1

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

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

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

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

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

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

Этот код работает в теге формы. В этом примере обратный вызов - это параметр функции, переданный 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>

8

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

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