2008-09-29 10 views
19

Dies ist ein Follow-up zu einer Antwort here.Wie behandelt man ein ActiveX-Ereignis in Javascript?

Ich habe ein benutzerdefiniertes ActiveX-Steuerelement, das ein Ereignis ("ReceiveMessage" mit einem "msg" -Parameter) ausgelöst wird, die von Javascript im Webbrowser behandelt werden muss. Historisch dies konnten wir die folgende IE-only-Syntax verwendet an verschiedenen Projekten zu erreichen:

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

Wenn jedoch in einem Layout, in dem die Steuer begraben wird, kann die Javascript nicht die Kontrolle finden. Insbesondere, wenn wir dies in eine einfache HTML-Seite einfügen, funktioniert es gut, aber wenn wir es in eine ASPX-Seite einfügen, die vom <Form>-Tag umschlossen wird, erhalten wir einen "MyControl ist undefiniert" -Fehler. Wir haben versucht, Variationen der folgenden:

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

... aber es ergibt sich der Javascript-Fehler "GetControl ist undefined."

Wie wird ein Ereignis behandelt, das von einem ActiveX-Steuerelement gesendet wird? Im Moment sind wir nur daran interessiert, dass dies im IE funktioniert. Dies muss ein benutzerdefiniertes ActiveX-Steuerelement für das sein, was wir tun.

Danke.

+0

Um einen Punkt zu klären - die getElementById funktioniert gut. Wir haben einen Verweis auf das Steuerelement, Javascript mag es einfach nicht, dass wir die :: Syntax mit diesem Verweis verwenden. – Raelshark

+0

Ich habe noch nie die :: Syntax gesehen, wo ist das dokumentiert? – AnthonyWJones

+0

Es ist schwer, tatsächliche Dokumentation dafür zu finden, aber hier ist ein Link zu einem MSDN-Artikel, der es erwähnt: http://msdn.microsoft.com/en-us/library/ms974564.aspx – Raelshark

Antwort

12

konnte ich diese Arbeit bekommen Sie das folgende Skript Blockformat, aber ich bin immer noch neugierig, ob dies der beste Weg ist:

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

In vielen Beispielen im Internet habe ich den folgenden Code gesehen } Auch wenn das obige funktioniert, beachten Sie, dass es fehlschlägt, wenn Ihr Ereignis mehrere Male ausgelöst wird. Das habe ich herausgefunden, als ich das ReceiveMessag-Ereignis an einen Timer im ActiveX-Steuerelement angeschlossen habe, der nach einem bestimmten Intervall ausgelöst hat. Jedes Mal, wenn das Ereignis ausgelöst wurde, wurde der Handler aufgerufen, wie oft das Ereignis ausgelöst wurde. (zB: 1. Feuer: 1 Mal, 2. Feuer: 2 Mal, 3. Feuer: 3 Mal). Keine Ahnung warum! Antworten? –

+0

Es scheint, wenn Sie die :: -Syntax innerhalb eines

0

Ich denke, dass die MyControl :: ReceiveMessage Beispiel funktioniert nicht weil das ActiveX-Steuerelement unter einem anderen Name oder in einem anderen Bereich verfügbar gemacht wird.

Mit dem Beispiel GetControl :: ReceiveMessage glaube ich, dass die Funktionsdefinition analysiert wird, bevor die GetControl-Referenz festgelegt wird, daher verweist es nicht auf ein gültiges Objekt und kann die Funktion nicht an das Objekt binden.

Ich würde dieses Problem angehen, indem Sie den MS-Skriptdebugger verwenden und versuchen, festzustellen, ob eine Standardreferenz für das Steuerelement unter einem anderen Namen oder in einem anderen Bereich (möglicherweise als untergeordnetes Element des Formulars) existiert. Wenn Sie die richtige Referenz für das Steuerelement ermitteln können, sollten Sie in der Lage sein, die Funktion ordnungsgemäß mit der Automagic :: -Methode, die der MSDN-Artikel angibt, zu binden.

Ein weiterer Gedanke, der Verweis auf dem Namen des Objekts basieren und nicht die ID, also versuchen Einstellung beide :)

1

Wenn Sie ein ActiveX-Element auf Ihrer Seite, die eine ID von ‚MyControl hat 'dann Javascript-Handler Syntax ist dies:

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

Ich denke nicht, dass das funktioniert, wenn das -Tag innerhalb eines Formulars ist. –

+0

@FrankSchwetterman Dieser Handler antwortet nur, wenn 'MyControl' im globalen Gültigkeitsbereich deklariert ist. Vielleicht bekommen nur die Objekte außerhalb von Formularen ihre "ID" im globalen Geltungsbereich? –

5

OK, aber wenn Sie C# verwenden (.NET 2.0) mit vererbten Usercontrol (ActiveX) ... Den einzigen Weg, um es Arbeit zu machen, ist durch „Erweiterung "Die Handler-Funktionalität des Ereignisses: http://www.codeproject.com/KB/dotnet/extend_events.aspx?display=Print

Der obige Projektlink von unserem Freund, Herrn Werner Willemsens, hat mein Projekt gerettet. Wenn Sie das nicht tun, kann das JavaScript nicht an den Event-Handler binden.

Er verwendete die "Erweiterung" auf eine komplexe Art und Weise aufgrund des Beispiels, das er wählte, aber wenn Sie es einfach machen und den Griff direkt an das Ereignis anhängen, funktioniert es auch. Die C# ActiveX sollte „ScriptCallbackObject“ zu unterstützen, wie unten um das Ereignis zu einer JavaScript-Funktion zu binden:

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; 
    } 

Natürlich haben Sie IObjectSafety und die anderen Sicherheits Sachen zu implementieren, um es besser zu arbeiten.

1

Ich fand diesen Code innerhalb eines Formular-Tags funktioniert. In diesem Beispiel ist callback ein Funktionsparameter, der von JavaScript an das ActiveX-Steuerelement übergeben wird, und callbackparam ist ein Parameter des Callback-Ereignisses, das im ActiveX-Steuerelement generiert wird. Auf diese Weise verwende ich den gleichen Event-Handler für alle Arten von Ereignissen, anstatt zu versuchen, eine Menge separater Event-Handler zu deklarieren.

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

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

8

Ich habe activex bereits in meinen Anwendungen verwendet. Ich platziere die Objekt-Tags im ASP.NET-Formular und das folgende JavaScript funktioniert für mich.

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

Hier ist der MSDN-Link http://msdn.microsoft.com/en-us/library/ms536343(VS.85).aspx – Zuhaib

+1

Ich versuchte dies und es funktionierte nicht mit ActiveX-Ereignissen –

+0

Es ist eine Weile her Ich habe das getestet, aber ich glaube, '.attachEvent()' funktioniert nur, wenn das Steuerelement mit statischem HTML oder möglicherweise 'document.write()' erstellt wurde. – Taudris

1

In meinem Fall brauchte ich eine Möglichkeit, ActiveX-Steuerelemente dynamisch zu erstellen und ihre Ereignisse anzuhören. Ich war in der Lage, so etwas zu erhalten zu arbeiten:

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

Und dann einen Handler für ein Ereignis zu registrieren:

//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); 
} 

Dieser Code ermöglicht es Ihnen, Verschlüsse zu verwenden, und minimiert den Umfang der eval ().

Das Element <object> des ActiveX-Steuerelements muss dem Dokument bereits hinzugefügt werden; Andernfalls wird der IE das Element nicht finden und Sie werden nur Skriptfehler bekommen.

+1

+1. Obwohl Ihre Antwort jquery-isms verwendet, ist dies eine nützliche Antwort, wenn Sie mit einer dynamischen Seite arbeiten. Ich hatte Erfolg mit der Methode 'attachEvent()' für das Objekt, um eine Listener-Funktion an ein ActiveX-Ereignis anzuhängen. Leider wird 'attachEvent()' im IE11-Modus nicht mehr unterstützt, also muss etwas wie die 'eval()' -Methode verwendet werden. Die Standardmethode 'addEventListener()' unterstützt keine ActiveX-basierten Ereignistypen. – ewh

Verwandte Themen