How to handle an ActiveX event in Javascript

不羁岁月 提交于 2019-11-26 22:11:49

I was able to get this working using the following script block format, but I'm still curious if this is the best way:

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

I have used activex in my applications before. i place the object tags in the ASP.NET form and the following JavaScript works for me.

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

OK, but if you are using C# (.NET 2.0) with inherited UserControl (ActiveX)... The only way to make it work is by "Extending" the event's handler functionality: http://www.codeproject.com/KB/dotnet/extend_events.aspx?display=Print

The above project link from our friend Mr. Werner Willemsens has saved my project. If you don't do that the javascript can't bind to the event handler.

He used the "extension" in a complex way due to the example he chose but if you make it simple, attaching the handle directly to the event itself, it also works. The C# ActiveX should support "ScriptCallbackObject" to bind the event to a javascript function like below:

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

Of course you have to implement IObjectSafety and the other security stuff to make it work better.

If you have an ActiveX element on your page that has an id of 'MyControl' then your javascript handler syntax is this:

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

I found this code works within a form tag. In this example, callback is a function parameter passed in by javascript to the ActiveX control, and callbackparam is a parameter of the callback event generated within the activeX control. This way I use the same event handler for whatever types of events, rather than try to declare a bunch of separate event handlers.

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

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

In my case, I needed a way to dynamically create ActiveX controls and listen to their events. I was able to get something like this to work:

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

And then to register a handler for an event:

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

This code allows you to use closures and minimizes the scope of the eval().

The ActiveX control's <object> element must already be added to the document; otherwise, IE will not find the element and you'll just get script errors.

I think that the MyControl::ReceiveMessage example does not work because the ActiveX control is being exposed with a different name or in a different scope.

With the example GetControl::ReceiveMessage, I believe that the function definition is being parsed before the GetControl reference is being set, thus it does not refer to a valid object and cannot bind the function to the object.

I would attack this problem by using the MS script debugger and trying to determine if a default reference for the control exists with a different name or in a different scope (possibly as a child of the form). If you can determine the correct reference for the control, you should be able to bind the function properly with the Automagic :: method that the MSDN article specifies.

One more thought, the reference may be based on the name of the object and not the ID, so try setting both :)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!