在C#中创建COM / ActiveXObject,使用JScript,使用简单的事件
我想在C#中创建一个COM对象,并通过JScript的IDispatch使用它.那部分很简单.
我也想在COM对象上实现简单的回调,类似于在浏览器中可用的XmlHttpRequest对象公开的事件.该模型允许Javascript附加事件处理程序,如下所示: var xmlhttp = new ActiveXObject("MSXML.XMLHTTP"); xmlhttp.onReadyStateChange = function() { ... }; 我想要我的客户端JScript代码看起来像这样: var myObject = new ActiveXObject("MyObject.ProgId"); myObject.onMyCustomEvent = function(..args here..) { ... }; C#代码是什么样的?我想要一般情况 – 我想能够将参数传回给Javascript fn. 我看过How can I make an ActiveX control written with C# raise events in JavaScript when clicked?,但是那里的答案看起来真的很复杂,而且使用起来很复杂. 从this article起,XMLHttpRequest事件似乎不是COM事件. onreadystatechange是IDispatch类型的属性.当脚本客户端将该属性设置为一个函数时,JScript会将其作为IDispatch对象进行编组. 剩下的唯一问题是从C#调用IDispatch. 解决方法
由于它是COM,首先定义一个接口.让我们保持简单.
[Guid("a5ee0756-0cbb-4cf1-9a9c-509407d5eed6")] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface IGreet { [DispId(1)] string Hello(string name); [DispId(2)] Object onHello { get; set; } } 然后,执行: [ProgId("Cheeso.Greet")] [ComVisible(true)] [Guid("bebcfaff-d2f4-4447-ac9f-91bf63b770d8")] [ClassInterface(ClassInterfaceType.None)] public partial class Greet : IGreet { public Object onHello { get; set; } public String Hello(string name) { var r = FireEvent(); return "Why,Hello," + name + "!!!" + r; } } 主要技巧是FireEvent方法.这对我有用 private string FireEvent() { if (onHello == null) return " (N/A)"; onHello .GetType() .InvokeMember ("",BindingFlags.InvokeMethod,null,onHello,new object [] {}); return "ok"; } 一起编译,注册regasm: %NET64%regasm.exe Cheeso.Greet.dll /register /codebase …然后使用它从JScript像这样: var greet = new ActiveXObject("Cheeso.Greet"),response; greet.onHello = function() { WScript.Echo("onHello (Javascript) invoked."); }; response = greet.Hello("Fred"); WScript.Echo("response: " + response); 有用. 您也可以从VBScript调用它: Sub onHello () WScript.Echo("onHello (VBScript) invoked.") End Sub Dim greet Set greet = WScript.CreateObject("Cheeso.Greet") greet.onHello = GetRef("onHello") Dim response response = greet.Hello("Louise") WScript.Echo("response: " & response) 要使用这种方法将参数从C#传递给JScript,我认为对象需要是IDispatch,但是当然你可以发回简单的值作为字符串,int等等,它们是被封送的,就像你所期望的那样. 例如,修改C#代码以发回自己的引用,并且编号42. onHello .GetType() .InvokeMember ("",new object [] { this,42 }); 那么你可以这样在jscript中 greet.onHello = function(arg,num) { WScript.Echo("onHello (Javascript) invoked."); WScript.Echo(" num = " + num + " stat=" + arg.status); }; 或者在VBScript中如此: Sub onHello (obj,num) WScript.Echo("onHello (VBScript) invoked. status=" & obj.status ) WScript.Echo(" num= " & num) End Sub 注意:您可以定义jscript事件处理函数来接受比调用“事件”时由C#对象发送的更少的参数.根据我的经验,您需要设计VBScript中的事件处理程序以明确接受正确的参数数量. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |