Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从ActiveX组件调用的JS回调如果不在主代码流中,则不会触发_Javascript_C#_Callback_Activex_Dom Events - Fatal编程技术网

Javascript 从ActiveX组件调用的JS回调如果不在主代码流中,则不会触发

Javascript 从ActiveX组件调用的JS回调如果不在主代码流中,则不会触发,javascript,c#,callback,activex,dom-events,Javascript,C#,Callback,Activex,Dom Events,我有一个ActiveX组件,可以扫描照片,将文件保存到客户端硬盘上的临时文件中,然后上传照片 我有一个“TwainMan”实例,它执行扫描部分,扫描完成后触发“ImageScanned”事件。这是我的主要代码流: scanner = new TwainMan(); scanner.ImageScanned += new ImageScannedEventHandler(Scanner_ImageScanned); 执行此操作的代码放入EventHandler委托方法“Scanner\u Ima

我有一个ActiveX组件,可以扫描照片,将文件保存到客户端硬盘上的临时文件中,然后上传照片

我有一个“TwainMan”实例,它执行扫描部分,扫描完成后触发“ImageScanned”事件。这是我的主要代码流:

scanner = new TwainMan();
scanner.ImageScanned += new ImageScannedEventHandler(Scanner_ImageScanned);
执行此操作的代码放入EventHandler委托方法“Scanner\u ImageScanned”:

在TriggerJSCallback方法中,我只触发我的JS回调:

private void TriggerJSCallback()
{
    EventHandler DataPreparingFinished = this.DataPreparingFinished;
    if (null != DataPreparingFinished) { DataPreparingFinished(this.tempFileName); }
}
请注意,如果我从主流程内触发JSCallback“DataPreparingFinished”,JS回调侦听器(在我的html页面中定义)工作正常,但是如果触发器“DataPreparingFinished”是从“Scanner\u ImageScanned”委托内触发的,而不是从主代码流触发的,则会出现问题

我做错了什么?有人能帮忙吗

下面是html页面中标记内的JS回调定义

<script for="AXTwain" event="DataPreparingFinished(args)" language="javascript" type="text/javascript">

    function AXTwain::DataPreparingFinished(args) {            
        alert("JS ALERT: SUCCESS!!! JS Callback working properly." + args);
        // alert("The temp file is stored on: " + AXTwain.TempFileName); 
    }

</script>

函数AXTwain::DataPreparingFinished(args){
警报(“JS警报:成功!!!JS回调工作正常。”+args);
//警报(“临时文件存储在:“+AXTwain.TempFileName”上);
}

如果我能展示更多的代码,也许会更好,这样你就能更好地了解我的问题到底是什么

让我们从顶部开始

下面是我的HTML页面,其中包括我的ActiveXObject实例化和JS回调/侦听器函数

<html xmlns="http://www.w3.org/1999/xhtml">
<head>

    <title>ActiveX TWAIN test page</title>

    <object id="AXTwain" name="AXTwain" classid="clsid:d8ea830e-38b0-4f3b-8be4-39c417c27583"></object>

</head>

<body onload="myload();">

    <h1 style="color:green;">AXTwain test page</h1> 

    <script type ="text/javascript">

        function myload() {
            if (AXTwain != null) {
                AXTwain.AcquireImage();
            }           
        }

    </script>

    <script for="AXTwain" event="DataPreparingFinished(args)" language="javascript" type="text/javascript">

        // The "for" attribute should be set to the name of instance of your COM component.
        // The "event" attribute should be set to the JavaScript function signature for the event.
        // The name of the JavaScript function is the instance name of your COM component, followed
        // by double colons, followed by the JavaScript signature of the event.

        function AXTwain::DataPreparingFinished(args) {            
            alert("JS ALERT: SUCCESS!!! JS Callback working properly." + args);            
        }

    </script>

</body>
</html>

ActiveX TWAIN测试页
AXTwain测试页
函数myload(){
if(AXTwain!=null){
AXTwain.AcquireImage();
}           
}
//“for”属性应设置为COM组件实例的名称。
//“event”属性应设置为事件的JavaScript函数签名。
//JavaScript函数的名称是COM组件的实例名称,后跟
//使用双冒号,后跟事件的JavaScript签名。
函数AXTwain::DataPreparingFinished(args){
警报(“JS警报:成功!!!JS回调工作正常。”+args);
}
下面是我的ActiveX包装器类

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace AXImageAcquisition
{
    #region ActiveX attributes
    [ProgId("AXImageAcquisition.AXTwain_01")]
    [Guid("d8ea830e-38b0-4f3b-8be4-39c417c27583")]
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [ComSourceInterfaces(typeof(IComEvents))]
    #endregion
    public class AXTwain
    {
        #region Class Properties and Settings

        private TwainMan scanner;
        private String tempFileName;
        public String TempFileName
        {
            get { return this.tempFileName; }
        }

        [ComVisible(false)]
        public delegate void EventHandler(string args);
        public event EventHandler DataPreparingFinished;

        public bool imageScanned = false;

        #endregion

        #region Class Constructors
        public AXTwain()
        {}
        #endregion

        #region Class Methods

        [ComVisible(true)]
        public void AcquireImage()
        {
            this.DataPreparingFinished += new EventHandler(Delegate_DataPreparingFinished);

            this.scanner = new TwainMan();
            this.scanner.ImageScanned += new ImageScannedEventHandler(Scanner_ImageScanned);            

            TriggerJSCallback(); // HERE IN THE MAIN CODE FLOW THE MESSAGE GETS TO JS!!!
        }

        /// <summary>
        /// Delegate that defines functionality for the ImageScanned event, defined in TwainMan class.
        /// </summary>
        /// <param name="Sender"></param>
        /// <param name="e"></param>
        public void Scanner_ImageScanned(object Sender, ImageScannedEventArgs e)
        {
            this.tempFileName = scanner.ToTempFile(e.Image);
            Upload(this.tempFileName);            

            TriggerJSCallback(); // HERE (NOT IN THE MAIN CODE FLOW) THE MESSAGE NEVER GETS TO JS!!! WHYYYY? :(
        }

        /// <summary>
        /// TODO!!!
        /// </summary>
        /// <param name="tempFileName"></param>
        private void Upload(string tempFileName)
        {
            // TODO
        }

        /// <summary>
        /// Test method for the DataPreparingFinished trigger.
        /// </summary>
        public void TriggerJSCallback()
        {           
            EventHandler DataPreparingFinished = this.DataPreparingFinished;
            if (null != DataPreparingFinished) DataPreparingFinished(this.tempFileName);
        }

        /// <summary>
        /// Delegate that defines functionality for the DataPreparingFinished event, which is defined in IComEvents.
        /// </summary>
        /// <param name="msg">Arguments passing from C# to JS.</param>
        void Delegate_DataPreparingFinished(string msg)
        {
            // MessageBox.Show("Delegate_DataPreparingFinished message! (C# code).\n Input message: " + msg);
        }

        #endregion
    }
}
使用系统;
使用System.Collections.Generic;
使用系统文本;
使用System.Runtime.InteropServices;
名称空间获取
{
#区域ActiveX属性
[ProgId(“AXImageAcquisition.AXTwain_01”)]
[Guid(“d8ea830e-38b0-4f3b-8be4-39c417c27583”)]
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(类型(IComeEvents))]
#端区
公共类AXTwain
{
#区域类属性和设置
私人吐温曼扫描仪;
私有字符串文件名;
公共字符串临时文件名
{
获取{返回this.tempFileName;}
}
[ComVisible(false)]
公共委托void EventHandler(字符串参数);
公共事件事件处理程序DataPreparingFinished;
公共bool imageScanned=假;
#端区
#区域类构造函数
公共AXTwain()
{}
#端区
#区域类方法
[ComVisible(true)]
公共图像()
{
this.DataPreparingFinished+=新事件处理程序(委托\u DataPreparingFinished);
this.scanner=new TwainMan();
this.scanner.ImageScanned+=新ImageScannedEventHandler(scanner\u ImageScanned);
TriggerJSCallback();//在主代码流中,消息到达JS!!!
}
/// 
///为Twinman类中定义的ImageScanned事件定义功能的委托。
/// 
/// 
/// 
公共无效扫描仪\u ImageScanned(对象发送器,ImageScannedEventArgs e)
{
this.tempFileName=scanner.ToTempFile(e.Image);
上载(此.tempFileName);
TriggerJSCallback();//此处(不在主代码流中)消息永远不会到达JS!!!WHYYYY?:(
}
/// 
///待办事项!!!
/// 
/// 
私有无效上载(字符串tempFileName)
{
//待办事项
}
/// 
///数据准备完成触发器的试验方法。
/// 
public void TriggerJSCallback()
{           
EventHandler DataPreparingFinished=this.DataPreparingFinished;
如果(null!=DataPreparingFinished)DataPreparingFinished(this.tempFileName);
}
/// 
///委托,用于定义在IComeEvents中定义的DataPreparingFinished事件的功能。
/// 
///从C#传递到JS的参数。
无效委托\u数据准备完成(字符串消息)
{
//MessageBox.Show(“委托数据准备完成的消息!(C代码)。\n输入消息:“+msg”);
}
#端区
}
}

如果你需要更多的代码,我也可以复制/粘贴代码的其余部分,即TWEMAN类和它的依赖关系。然而,所有这些都是从一个代码项目教程中提取的。BTW,感谢作者。

很难确定,因为我不从C语言写ActiveX组件,但是在C++中,这样的回调会有这样的效果。如果从主线程以外的线程调用。ActiveX通常希望所有调用都发生在主线程上。不过,也有一些方法可以让其他线程使用ActiveX,而且C#可能会自动为您执行此操作,因此在C#中这可能并不总是准确的


我建议您找到一种在主线程上触发函数的方法;我知道在Silverlight中使用Dispatcher可以实现这一点;也许您可以找到类似的方法?无论如何,这就是我要尝试的。

Taxilian,衷心感谢您的回复。
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace AXImageAcquisition
{
    #region ActiveX attributes
    [ProgId("AXImageAcquisition.AXTwain_01")]
    [Guid("d8ea830e-38b0-4f3b-8be4-39c417c27583")]
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [ComSourceInterfaces(typeof(IComEvents))]
    #endregion
    public class AXTwain
    {
        #region Class Properties and Settings

        private TwainMan scanner;
        private String tempFileName;
        public String TempFileName
        {
            get { return this.tempFileName; }
        }

        [ComVisible(false)]
        public delegate void EventHandler(string args);
        public event EventHandler DataPreparingFinished;

        public bool imageScanned = false;

        #endregion

        #region Class Constructors
        public AXTwain()
        {}
        #endregion

        #region Class Methods

        [ComVisible(true)]
        public void AcquireImage()
        {
            this.DataPreparingFinished += new EventHandler(Delegate_DataPreparingFinished);

            this.scanner = new TwainMan();
            this.scanner.ImageScanned += new ImageScannedEventHandler(Scanner_ImageScanned);            

            TriggerJSCallback(); // HERE IN THE MAIN CODE FLOW THE MESSAGE GETS TO JS!!!
        }

        /// <summary>
        /// Delegate that defines functionality for the ImageScanned event, defined in TwainMan class.
        /// </summary>
        /// <param name="Sender"></param>
        /// <param name="e"></param>
        public void Scanner_ImageScanned(object Sender, ImageScannedEventArgs e)
        {
            this.tempFileName = scanner.ToTempFile(e.Image);
            Upload(this.tempFileName);            

            TriggerJSCallback(); // HERE (NOT IN THE MAIN CODE FLOW) THE MESSAGE NEVER GETS TO JS!!! WHYYYY? :(
        }

        /// <summary>
        /// TODO!!!
        /// </summary>
        /// <param name="tempFileName"></param>
        private void Upload(string tempFileName)
        {
            // TODO
        }

        /// <summary>
        /// Test method for the DataPreparingFinished trigger.
        /// </summary>
        public void TriggerJSCallback()
        {           
            EventHandler DataPreparingFinished = this.DataPreparingFinished;
            if (null != DataPreparingFinished) DataPreparingFinished(this.tempFileName);
        }

        /// <summary>
        /// Delegate that defines functionality for the DataPreparingFinished event, which is defined in IComEvents.
        /// </summary>
        /// <param name="msg">Arguments passing from C# to JS.</param>
        void Delegate_DataPreparingFinished(string msg)
        {
            // MessageBox.Show("Delegate_DataPreparingFinished message! (C# code).\n Input message: " + msg);
        }

        #endregion
    }
}