如何在Javascript中处理ActiveX事件

问题描述:

这是对here回答的后续操作。如何在Javascript中处理ActiveX事件

我有一个自定义的ActiveX控件引发了一个事件(“ReceiveMessage”带有“msg”参数),需要在Web浏览器中由Javascript处理。从历史上看,我们已经能够使用下面的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控件。

谢谢。

+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

我可以使用下面的脚本块格式得到这个工作,但我仍然好奇,如果这是最好的方法:

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

我认为MyControl :: ReceiveMessage例如不工作因为ActiveX控件正在以不同的名称或不同的范围显示。

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

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

还有一个思想,可以参照基于对象的名称,而不是ID,所以尽量同时设置:)

如果你有一个具有“MyControl的ID在网页上的ActiveX元件“那么你的JavaScript处理语法是这样的:

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

OK,但如果你使用的是C#(.NET 2.0)与继承的用户控件(的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的和其他安全东西,以使其更好地工作中。

我发现此代码在表单标签内工作。在这个例子中,回调是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。我把对象标签放在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); 
} 

对我而言,我需要一种动态创建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浏览器将无法找到该元素,您只会收到脚本错误。