单击时,如何使使用 C# 编写的 ActiveX 控件在 JavaScript 中引发事件?

Posted

技术标签:

【中文标题】单击时,如何使使用 C# 编写的 ActiveX 控件在 JavaScript 中引发事件?【英文标题】:How can I make an ActiveX control written with C# raise events in JavaScript when clicked? 【发布时间】:2009-09-21 16:58:49 【问题描述】:

我已经在 SO 上看到了一些与此相关的问题,但我认为我的问题完全不同,不会被视为重复(如果我错了,请告诉我)。

我有一个用 C# 编写的 ActiveX 控件,虽然它大部分时间都在工作,但我想在单击它时在 javascript 中引发一个事件(它显示一个图像,因此它是页面上的一个可视元素)。

我想要完成的最终目标与它是一个 <span> 标记并没有什么不同,它有一个 onclick 事件以在单击标记区域时引发一个 JavaScript 函数。

上面的大部分stuff I've read 都非常详细地介绍了如何处理ActiveX 控件中的事件以及来回发送信息,这很好,但似乎过于复杂。我不想与 ActiveX 控件进行通信,我只需要一个 JavaScript 函数在我单击它时触发它,其方式类似于 <span><div> 标记。我可以处理 JavaScript 中的所有其他内容。简单地将控件包装在 <span><div> 中并带有 onclick 事件没有任何效果 - ActiveX 控件几乎会覆盖它。

对于用 C# 编写的 ActiveX 控件,是否有一种简单的方法来处理这个问题?

我想另一种说法是 - 我正在使用第三方控件,我们必须使用类似于以下的代码来让它通过 JavaScript 与我们的 html 页面进行通信

<script type="text/javascript" event="OnMouseClick(index)" for="AXObjectName"> 
        <!--
         AXObjectName_OnMouseClick(index);
        //-->
</script>

AXObjectName 是控件的名称/ID,AXObjectName_OnMouseClick 是它将在我的代码中触发的 JavaScript 函数的名称,传递一个 index 参数。但是,我需要做什么才能在控件中设置像OnMouseClick 这样的方法?如果我不想传递任何实际信息(即没有index),我什至必须走这么远吗?

【问题讨论】:

我猜你已经看过这个代码示例:c-sharpcorner.com/UploadFile/dsandor/… 我实际上只是包含了链接,以便可以在我的另一台计算机上找到它。我将自己尝试一个 ActiveX 控件实验,也许会弄清楚事件的事情。它看起来相对简单。 @MusiGenesis:是的,它是我跟随的其中之一。但是,它没有展示与 ActiveX 控件交互如何对页面中的 JavaScript 产生任何影响。 【参考方案1】:

ActiveX 事件是通过 COM 处理的,因此您需要深入研究一下不幸的是

使用 COM 要记住的是,一切都是通过接口处理的,因此您通常需要创建两个接口,一个用于任何属性,一个用于您的事件。

事件的关键是使用 ComSourceInterfaces 属性标记您的类,MSDN 将其描述为“标识作为属性类的 COM 事件源公开的接口列表。”

这个简单的类结构应该适合你(过去也适合我)。

namespace MyActiveX

    [Guid("Your-GUID") ,InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IActiveXEvents
    
        [DispId(1)]
        void OnMouseClick(int index);
    

    [Guid("Another-GUID"),InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IActiveX
           
        //[DispId(1)]
        // Any properties you want here like this
        // string aProperty  get; set;         
    

    [ComVisible(true)]
    [Guid("Yet-Another-GUID"), ClassInterface(ClassInterfaceType.None)]
    [ProgId("MyActiveX")]
    [ComSourceInterfaces(typeof(IActiveXEvents))]
    public partial class MyActiveX : UserControl, IActiveX
    
        public delegate void OnMouseClickHandler(int index);

        public event OnMouseClickHandler OnMouseClick;

        // Dummy Method to use when firing the event
        private void MyActiveX_nMouseClick(int index)
        

        

        public MyActiveX()
        
            InitializeComponent();

            // Bind event
            this.OnMouseClick = new OnMouseClickHandler(this.MyActiveX_MouseClick)
        

        public void FireTheEvent()
        
            int index = -1;
            this.OnMouseClick(index);
               
    

如果您不需要任何属性,您可以只排除 IActiveX 接口。此外,如果您要使用 Click 事件,则需要将其标记为 new 以将其传递给 COM。

【讨论】:

哈哈 :) 这是一篇非常好的博文,但是关于 ActiveX 和 C# 的 good 信息很难获得。我仍然知道如何做到这一点:***.com/questions/746822/… @MusiGenesis 我开始相信这是微软扼杀 ActiveX 的险恶计划的一部分。对我们仍然需要生产这项技术的人没有帮助。在 VB .NET 中,事情要容易一点,请参阅codeproject.com/KB/COM/VS2005ComDllWalkThru.aspx 对于那些寻找 Schnapple 链接的人,链接已更新为blog.ianchivers.com/2011/01/… 这比这更容易。见***.com/questions/11175145/…

以上是关于单击时,如何使使用 C# 编写的 ActiveX 控件在 JavaScript 中引发事件?的主要内容,如果未能解决你的问题,请参考以下文章

ActiveX 使用 C# 返回的 VARIANT 为 NULL

如何将字节数组从 c# 传递到 MFC ActiveX

使用C#开发ActiveX控件

双击ActiveX控件时如何禁用Visual Basic对话框

vs2010 下使用C#开发activeX控件

您将使用哪种 C# 项目类型来重新开发 MFC C++ activex 控件?