在C#中创建COM / ActiveXObject的,从JScript中使用,具有简单的事件 [英] Create COM/ActiveXObject in C#, use from JScript, with simple event

查看:1253
本文介绍了在C#中创建COM / ActiveXObject的,从JScript中使用,具有简单的事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建在C#中的COM对象,并通过IDispatch接口从JScript中使用它。这部分是非常简单的。

I'd like to create a COM object in C#, and use it via IDispatch from JScript. That part is pretty simple.

我也想实现COM对象简单的回调,类似于XmlHttpRequest对象是在浏览器中使用的暴露事件。这种模式允许JavaScript附加事件处理程序是这样的:

I also want to implement simple callbacks on the COM object, similar to the event exposed by the XmlHttpRequest object that is usable in a browser. That model allows Javascript to attach event handlers like this:

var xmlhttp = new ActiveXObject("MSXML.XMLHTTP"); 
xmlhttp.onReadyStateChange = function() {
  ...
};



我希望我的客户端JScript代码看起来是这样的:

I want my client-side JScript code to look like this:

var myObject = new ActiveXObject("MyObject.ProgId");
myObject.onMyCustomEvent = function(..args here..) { 
   ...
};



什么是C#代码是什么样子?我想一般情况下 - 我希望能够通过参数回给Javascript新生力量。

What does the C# code look like? I'd like the general case - I'd like to be able to pass arguments back to the Javascript fn.

我见过的我怎样才能让用C#编写ActiveX控件提高JavaScript事件点击时<? / A>,但答案有看起来很复杂,实施和复杂的使用。

I've seen How can I make an ActiveX control written with C# raise events in JavaScript when clicked? , but the answers there look really complicated to implement, and complicated to use.

从的这篇文章,似乎XMLHttpRequest的事件并不COM事件。在的onreadystatechange 是类型的属性的IDispatch 。当客户端脚本设置该属性给一个函数,JScript的老帅它作为一个IDispatch对象。

From this article, it seems that XMLHttpRequest events are not COM events. The onreadystatechange is a property of type IDispatch. When script clients set that property to a function, JScript marshals it as an IDispatch object.

这仍然是唯一的问题是然后再从C#调用了IDispatch。

The only problem that remains is then to invoke the IDispatch from C#.

推荐答案

由于它的COM,通过定义界面启动。让我们保持它的简单。

Since it's COM, start by defining an interface. Let's keep it simple.

[Guid("a5ee0756-0cbb-4cf1-9a9c-509407d5eed6")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IGreet
{
    [DispId(1)]
    string Hello(string name);

    [DispId(2)]
    Object onHello { get; set; }
}



然后,执行:

Then, the implementation:

[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 方法。这为我工作。

The main trick is the FireEvent method. This worked for me.

    private string FireEvent()
    {
        if (onHello == null) return " (N/A)";
        onHello
            .GetType()
            .InvokeMember
            ("",
             BindingFlags.InvokeMethod,
             null,
             onHello,
             new object [] {});

        return "ok";
    }



编译所有的在一起,regasm注册它:

Compile that all together, register it with regasm:

%NET64%\regasm.exe Cheeso.Greet.dll /register /codebase

...然后用它从JScript中是这样的:

...And then use it from JScript like this:

var greet = new ActiveXObject("Cheeso.Greet"), response;
greet.onHello = function() {
    WScript.Echo("onHello (Javascript) invoked.");
};
response = greet.Hello("Fred");
WScript.Echo("response: " + response);



它的工作原理。

It works.

您也可以从VBScript中调用它:

You can also call it from 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接口,当然你可以发送编组为字符串,整数,等等这是封送如你所愿回到简单的值。


To pass parameters back from C# to JScript with this approach, I think objects need to be IDispatch, but of course you can send back simple values marshaled as string, int, and so on which are marshaled as you would expect.

例如,修改C#代码来引用发回它本身,而数42

For example, modify the C# code to send back a reference to itself, and the number 42.

        onHello
            .GetType()
            .InvokeMember
            ("",
             BindingFlags.InvokeMethod,
             null,
             onHello,
             new object [] { this, 42 });



然后,你可以在像这样的JScript:

Then, you can get that in jscript like so:

greet.onHello = function(arg, num) {
    WScript.Echo("onHello (Javascript) invoked.");
    WScript.Echo("  num = " + num + "  stat=" + arg.status);
};

或者VBScript中,像这样:

Or in VBScript like so:

Sub onHello (obj, num)
    WScript.Echo("onHello (VBScript) invoked. status=" & obj.status )
    WScript.Echo("  num= " & num)
End Sub

注意:你可以定义你的JScript事件处理程序函数接受比由C#对象调用事件时,发送较少ARGS。根据我的经验,你需要设计VBScript中的事件处理程序,明确接受正确的参数个数。

NB: You can define your jscript event handler function to accept fewer args than are sent by the C# object when invoking the "event". In my experience you need to design the event handler in VBScript to explicitly accept the correct number of arguments.

这篇关于在C#中创建COM / ActiveXObject的,从JScript中使用,具有简单的事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆