如何在Javascript中处理ActiveX事件

时间:2008-09-29 21:35:24

标签: javascript events activex

这有点是答案here的后续行动。

我有一个自定义ActiveX控件,它引发了一个需要在Web浏览器中由Javascript处理的事件(带有“msg”参数的“ReceiveMessage”)。从历史上看,我们已经能够使用以下仅IE语法在不同项目中实现此目的:

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

但是,当在掩埋控件的布局内部时,Javascript无法找到控件。具体来说,如果我们把它放到一个普通的HTML页面中它可以正常工作,但是如果我们将它放入由<Form>标签包装的ASPX页面中,我们会得到一个“MyControl is undefined”错误。我们尝试过以下各种变体:

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

...但是它会导致Javascript错误“GetControl未定义。”

处理从ActiveX控件发送的事件的正确方法是什么?现在我们只对在IE中工作感兴趣。这必须是我们正在做的自定义ActiveX控件。

感谢。

7 个答案:

答案 0 :(得分:13)

我能够使用以下脚本块格式来实现这一点,但我仍然很好奇这是否是最佳方式:

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

答案 1 :(得分: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);
}

答案 2 :(得分:5)

好的,但如果你使用C#(。NET 2.0)继承了UserControl(ActiveX)... 使其工作的唯一方法是“扩展”事件的处理程序功能: http://www.codeproject.com/KB/dotnet/extend_events.aspx?display=Print

我们的朋友Werner Willemsens先生的上述项目链接已经保存了我的项目。 如果你不这样做,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和其他安全措施才能使其更好地运作。

答案 3 :(得分:1)

如果您的网页上有一个id为“MyControl”的ActiveX元素,那么您的javascript处理程序语法就是:

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

答案 4 :(得分: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>

  

答案 5 :(得分: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将找不到该元素,您只会收到脚本错误。

答案 6 :(得分:0)

我认为MyControl :: ReceiveMessage示例不起作用,因为ActiveX控件使用不同的名称或不同的范围公开。

使用示例GetControl :: ReceiveMessage,我相信在设置GetControl引用之前正在解析函数定义,因此它不引用有效对象,也不能将函数绑定到对象。

我会通过使用MS脚本调试器并尝试确定控件的默认引用是否存在具有不同名称或不同范围(可能作为表单的子级)来解决此问题。如果您可以确定控件的正确引用,则应该能够使用MSDN文章指定的Automagic ::方法正确绑定该函数。

还有一个想法,引用可能是基于对象的名称而不是ID,所以尝试同时设置:)